import pandas as pd import matplotlib.pyplot as plt import seaborn as sns # Set font (optional) plt.rcParams['font.family'] = 'Segoe UI Emoji' # Load data df = pd.read_csv('synthetic_elderly_transactions.csv', parse_dates=['timestamp']) df['date'] = df['timestamp'].dt.date # Set style sns.set_style("whitegrid") # Create dashboard layout with extra space fig = plt.figure(figsize=(20, 24), constrained_layout=True) gs = fig.add_gridspec(3, 2, height_ratios=[1, 1, 1.2]) # Bottom plot gets more room # --- Plot 1: Normal vs Suspicious --- ax1 = fig.add_subplot(gs[0, 0]) sns.countplot(data=df, x='is_anomalous', hue='is_anomalous', palette='Set2', legend=False, ax=ax1) ax1.set_title("Normal vs Suspicious Transactions", fontsize=16, pad=15) ax1.set_xticks([0, 1]) ax1.set_xticklabels(['Normal', 'Suspicious'], fontsize=12) ax1.set_xlabel("Transaction Type", fontsize=13, labelpad=10) ax1.set_ylabel("Count", fontsize=13, labelpad=10) # --- Plot 2: Transaction Amount Distribution --- ax2 = fig.add_subplot(gs[0, 1]) sns.histplot(data=df, x='amount', hue='is_anomalous', kde=True, bins=50, palette='coolwarm', ax=ax2) ax2.set_title("Transaction Amount Distribution", fontsize=16, pad=15) ax2.set_xlabel("Amount", fontsize=13, labelpad=10) ax2.set_ylabel("Count", fontsize=13, labelpad=10) ax2.tick_params(axis='x', rotation=30) # --- Plot 3: Transaction Types --- ax3 = fig.add_subplot(gs[1, 0]) sns.countplot(data=df, x='transaction_type', hue='is_anomalous', palette='muted', ax=ax3) ax3.set_title("Transaction Types by Normal/Suspicious", fontsize=16, pad=15) ax3.set_xlabel("Transaction Type", fontsize=13, labelpad=10) ax3.set_ylabel("Count", fontsize=13, labelpad=10) ax3.tick_params(axis='x', rotation=30) # --- Plot 4: Top Merchants --- ax4 = fig.add_subplot(gs[1, 1]) sns.countplot( data=df, y='merchant', order=df['merchant'].value_counts().index, hue=None, palette='viridis', ax=ax4 ) ax4.set_title("Most Frequent Merchants", fontsize=16, pad=15) ax4.set_xlabel("Count", fontsize=13, labelpad=10) ax4.set_ylabel("Merchant", fontsize=13, labelpad=10) ax4.tick_params(axis='y', labelsize=11) # --- Plot 5: Time Series --- ax5 = fig.add_subplot(gs[2, :]) # Full width transactions_per_day = df.groupby('date').size() ax5.plot(transactions_per_day.index, transactions_per_day.values, color='tab:blue', linewidth=2) ax5.set_title("🗓️ Transactions Over Time", fontsize=18, pad=20) ax5.set_xlabel("Date", fontsize=13, labelpad=10) ax5.set_ylabel("Number of Transactions", fontsize=13, labelpad=10) ax5.tick_params(axis='x', rotation=45) # Show clean and clear dashboard plt.show()