Spaces:
Sleeping
Sleeping
import streamlit as st | |
import pandas as pd | |
import matplotlib.pyplot as plt | |
import seaborn as sns | |
# Initialize the DataFrame in the session state if it doesn't exist | |
if 'expenses_df' not in st.session_state: | |
columns = ['Date', 'Category', 'Description', 'Amount'] | |
st.session_state.expenses_df = pd.DataFrame(columns=columns) | |
# Streamlit app layout | |
st.title('Expense Tracker') | |
# Add new expense entry | |
st.subheader("Add New Expense") | |
date = st.date_input("Date") | |
category = st.selectbox("Category", ['Food', 'Transport', 'Entertainment', 'Other']) | |
description = st.text_input("Description") | |
amount = st.number_input("Amount", min_value=0.0, format="%.2f") | |
if st.button("Add Expense"): | |
new_expense = pd.DataFrame([[date, category, description, amount]], columns=st.session_state.expenses_df.columns) | |
st.session_state.expenses_df = pd.concat([st.session_state.expenses_df, new_expense], ignore_index=True) | |
st.success(f"Added expense: {description} - ${amount:.2f}") | |
# Display all expenses | |
st.subheader("Expenses List") | |
st.write(st.session_state.expenses_df) | |
# Ensure 'Amount' is numeric (convert if necessary) | |
st.session_state.expenses_df['Amount'] = pd.to_numeric(st.session_state.expenses_df['Amount'], errors='coerce') | |
# Show category summary | |
st.subheader("Category Summary") | |
category_summary = st.session_state.expenses_df.groupby('Category')['Amount'].sum().reset_index() | |
st.write(category_summary) | |
# Generate individual bar and pie charts per Category (grouped by Description) | |
st.subheader("Bar Charts and Pie Charts per Category") | |
# Get all unique categories | |
unique_categories = st.session_state.expenses_df['Category'].unique() | |
# Loop through each unique category to plot bar and pie charts by description | |
for category in unique_categories: | |
category_df = st.session_state.expenses_df[st.session_state.expenses_df['Category'] == category] | |
# Bar chart: Expense distribution by description for this category | |
fig, ax = plt.subplots(figsize=(10, 6)) | |
sns.barplot(x='Description', y='Amount', data=category_df, ax=ax) | |
ax.set_title(f'Total Expenses for Category: {category}') | |
ax.set_xlabel('Description') | |
ax.set_ylabel('Amount Spent ($)') | |
ax.set_xticklabels(ax.get_xticklabels(), rotation=45) | |
st.pyplot(fig) | |
# Pie chart: Expense distribution by description for this category | |
fig, ax = plt.subplots(figsize=(8, 8)) | |
description_summary = category_df.groupby('Description')['Amount'].sum().reset_index() | |
description_summary.set_index('Description')['Amount'].plot(kind='pie', autopct='%1.1f%%', legend=False, ax=ax) | |
ax.set_title(f'Expense Distribution for Category: {category}') | |
ax.set_ylabel('') # Hide ylabel | |
st.pyplot(fig) | |
# Create overall bar and pie chart for all categories | |
# Bar chart for total expenses by category | |
st.subheader("Overall Expenses by Category") | |
fig, ax = plt.subplots(figsize=(10, 6)) | |
sns.barplot(x='Category', y='Amount', data=category_summary, ax=ax) | |
ax.set_title('Total Expenses by Category (Overall)') | |
ax.set_xlabel('Category') | |
ax.set_ylabel('Amount Spent ($)') | |
ax.set_xticklabels(ax.get_xticklabels(), rotation=45) | |
st.pyplot(fig) | |
# Pie chart for expense distribution by category | |
st.subheader("Overall Expense Distribution") | |
fig, ax = plt.subplots(figsize=(8, 8)) | |
category_summary.set_index('Category')['Amount'].plot(kind='pie', autopct='%1.1f%%', legend=False, ax=ax) | |
ax.set_title('Expense Distribution by Category (Overall)') | |
ax.set_ylabel('') # Hide ylabel | |
st.pyplot(fig) | |
# Save the expenses to a CSV file | |
st.download_button( | |
label="Download Expenses as CSV", | |
data=st.session_state.expenses_df.to_csv(index=False), | |
file_name="expenses.csv", | |
mime="text/csv" | |
) | |