File size: 2,695 Bytes
d16c0f6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
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()