|
import pandas as pd
|
|
import matplotlib.pyplot as plt
|
|
import seaborn as sns
|
|
|
|
|
|
plt.rcParams['font.family'] = 'Segoe UI Emoji'
|
|
|
|
|
|
df = pd.read_csv('synthetic_elderly_transactions.csv', parse_dates=['timestamp'])
|
|
df['date'] = df['timestamp'].dt.date
|
|
|
|
|
|
sns.set_style("whitegrid")
|
|
|
|
|
|
fig = plt.figure(figsize=(20, 24), constrained_layout=True)
|
|
gs = fig.add_gridspec(3, 2, height_ratios=[1, 1, 1.2])
|
|
|
|
|
|
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)
|
|
|
|
|
|
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)
|
|
|
|
|
|
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)
|
|
|
|
|
|
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)
|
|
|
|
|
|
ax5 = fig.add_subplot(gs[2, :])
|
|
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)
|
|
|
|
|
|
plt.show()
|
|
|