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" )