BlakeL commited on
Commit
ae06fdb
·
verified ·
1 Parent(s): 307db4e

Upload 2 files

Browse files
Files changed (1) hide show
  1. graphs.py +152 -0
graphs.py ADDED
@@ -0,0 +1,152 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import matplotlib.pyplot as plt
2
+ import numpy as np
3
+ import io
4
+ import base64
5
+
6
+ # Pie chart for conflict prediction
7
+
8
+ def create_conflict_pie_chart(result):
9
+ fig, ax = plt.subplots(figsize=(3, 2))
10
+ if result['conflict_level'] == 'High Risk':
11
+ colors = ['#ff6b6b', '#4ecdc4']
12
+ sizes = [result['confidence'], 1 - result['confidence']]
13
+ labels = ['High Risk', 'Low Risk']
14
+ else:
15
+ colors = ['#4ecdc4', '#ff6b6b']
16
+ sizes = [result['confidence'], 1 - result['confidence']]
17
+ labels = ['Low Risk', 'High Risk']
18
+ wedges, texts, autotexts = ax.pie(sizes, labels=labels, colors=colors, autopct='%1.1f%%',
19
+ startangle=90, explode=(0.1, 0))
20
+ ax.set_title(f'Conflict Risk Prediction\nConfidence: {result["confidence"]:.1%}',
21
+ fontsize=10, fontweight='bold', pad=10)
22
+ for autotext in autotexts:
23
+ autotext.set_color('white')
24
+ autotext.set_fontweight('bold')
25
+ ax.legend(wedges, labels, title="Risk Levels", loc="center left", bbox_to_anchor=(1, 0, 0.5, 1))
26
+ plt.tight_layout()
27
+ img_buffer = io.BytesIO()
28
+ plt.savefig(img_buffer, format='png', dpi=300, bbox_inches='tight')
29
+ img_buffer.seek(0)
30
+ img_base64 = base64.b64encode(img_buffer.getvalue()).decode()
31
+ plt.close()
32
+ return f"data:image/png;base64,{img_base64}"
33
+
34
+ # Histogram for addiction score (not currently used, but included for completeness)
35
+ def create_addiction_score_chart(result, data=None):
36
+ fig, ax = plt.subplots(figsize=(3, 2))
37
+ if data is not None and 'Addicted_Score' in data.columns:
38
+ scores = data['Addicted_Score'].dropna()
39
+ else:
40
+ np.random.seed(42)
41
+ scores = np.random.normal(5.5, 1.5, 1000)
42
+ scores = np.clip(scores, 1, 10)
43
+ n, bins, patches = ax.hist(scores, bins=20, alpha=0.7, color='#4ecdc4',
44
+ edgecolor='black', linewidth=0.5)
45
+ predicted_score = result['predicted_score']
46
+ ax.axvline(x=predicted_score, color='#ff6b6b', linewidth=3,
47
+ label=f'Your Prediction: {predicted_score:.2f}')
48
+ if 'confidence' in result:
49
+ confidence = result['confidence']
50
+ ax.axvspan(predicted_score - 0.5, predicted_score + 0.5,
51
+ alpha=0.3, color='#ff6b6b',
52
+ label=f'Confidence: {confidence:.2f}')
53
+ ax.set_title('Addiction Score Distribution with Your Prediction',
54
+ fontsize=10, fontweight='bold', pad=10)
55
+ ax.set_xlabel('Addiction Score (1-10)', fontsize=8, fontweight='bold')
56
+ ax.set_ylabel('Frequency', fontsize=8, fontweight='bold')
57
+ ax.axvspan(1, 3, alpha=0.2, color='green', label='Low Addiction (1-3)')
58
+ ax.axvspan(3, 7, alpha=0.2, color='orange', label='Moderate Addiction (3-7)')
59
+ ax.axvspan(7, 10, alpha=0.2, color='red', label='High Addiction (7-10)')
60
+ ax.legend(loc='upper right', fontsize=7)
61
+ ax.grid(True, alpha=0.3)
62
+ ax.set_xlim(0, 10)
63
+ plt.tight_layout()
64
+ img_buffer = io.BytesIO()
65
+ plt.savefig(img_buffer, format='png', dpi=300, bbox_inches='tight')
66
+ img_buffer.seek(0)
67
+ img_base64 = base64.b64encode(img_buffer.getvalue()).decode()
68
+ plt.close()
69
+ return f"data:image/png;base64,{img_base64}"
70
+
71
+ # Gauge chart for addiction score
72
+ def create_addiction_gauge_chart(result):
73
+ fig, ax = plt.subplots(figsize=(3, 2), subplot_kw={'projection': 'polar'})
74
+ predicted_score = result['predicted_score']
75
+ angle = (predicted_score - 1) * 20
76
+ theta = np.linspace(0, np.pi, 100)
77
+ ax.plot(theta, [1]*100, 'k-', linewidth=3)
78
+ low_angle = np.linspace(0, 2*20*np.pi/180, 50)
79
+ ax.fill_between(low_angle, 0, 1, alpha=0.3, color='green', label='Low (1-3)')
80
+ mod_angle = np.linspace(2*20*np.pi/180, 6*20*np.pi/180, 50)
81
+ ax.fill_between(mod_angle, 0, 1, alpha=0.3, color='orange', label='Moderate (3-7)')
82
+ high_angle = np.linspace(6*20*np.pi/180, np.pi, 50)
83
+ ax.fill_between(high_angle, 0, 1, alpha=0.3, color='red', label='High (7-10)')
84
+ needle_angle = angle * np.pi / 180
85
+ ax.plot([needle_angle, needle_angle], [0, 1.2], 'k-', linewidth=4, label=f'Your Score: {predicted_score:.1f}')
86
+ ax.plot(needle_angle, 1.2, 'ko', markersize=10, markeredgecolor='white', markeredgewidth=2)
87
+ ax.set_title(f'Addiction Score Gauge\nPredicted: {predicted_score:.1f}/10',
88
+ fontsize=10, fontweight='bold', pad=10)
89
+ ax.set_xticks([])
90
+ ax.set_yticks([])
91
+ ax.set_ylim(0, 1.3)
92
+ ax.text(0, 1.4, 'Low\n(1-3)', ha='center', va='center', fontsize=8, fontweight='bold')
93
+ ax.text(np.pi/2, 1.4, 'Moderate\n(3-7)', ha='center', va='center', fontsize=8, fontweight='bold')
94
+ ax.text(np.pi, 1.4, 'High\n(7-10)', ha='center', va='center', fontsize=8, fontweight='bold')
95
+ if 'confidence' in result:
96
+ confidence = result['confidence']
97
+ ax.text(0, -0.3, f'Confidence: {confidence:.2f}', ha='center', va='center',
98
+ fontsize=8, fontweight='bold', bbox=dict(boxstyle="round,pad=0.3", facecolor="lightblue"))
99
+ plt.tight_layout()
100
+ img_buffer = io.BytesIO()
101
+ plt.savefig(img_buffer, format='png', dpi=300, bbox_inches='tight')
102
+ img_buffer.seek(0)
103
+ img_base64 = base64.b64encode(img_buffer.getvalue()).decode()
104
+ plt.close()
105
+ return f"data:image/png;base64,{img_base64}"
106
+
107
+ # Clustering: Elbow and Sleep vs Age scatter plot
108
+ def create_clustering_charts(result, cluster_df=None, user_sleep=None, user_age=None, user_cluster=None, cluster_labels_map=None):
109
+ fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
110
+ optimal_k = 3
111
+ k_values = range(1, 11)
112
+ inertias = [150, 120, 85, 65, 55, 50, 47, 45, 43, 42]
113
+ ax1.plot(k_values, inertias, 'bo-', linewidth=2, markersize=8)
114
+ ax1.set_xlabel('Number of Clusters (k)', fontweight='bold')
115
+ ax1.set_ylabel('Inertia', fontweight='bold')
116
+ ax1.set_title('Elbow Method: Optimal K Selection', fontsize=12, fontweight='bold')
117
+ ax1.grid(True, alpha=0.3)
118
+ ax1.axvline(x=optimal_k, color='red', linestyle='--', alpha=0.7, label=f'Optimal k = {optimal_k}')
119
+ ax1.legend()
120
+ # Scatter plot: Sleep vs Age colored by cluster (always 3 clusters/colors)
121
+ if cluster_df is not None and cluster_labels_map is not None:
122
+ colors = ['#4ecdc4', '#ffd93d', '#ff6b6b']
123
+ for cluster in range(optimal_k):
124
+ sub = cluster_df[cluster_df['cluster'] == cluster]
125
+ color = colors[cluster % len(colors)]
126
+ label = cluster_labels_map.get(cluster, f'Cluster {cluster}')
127
+ ax2.scatter(sub['Sleep_Hours_Per_Night'], sub['Age'], c=color, alpha=0.7, s=50, label=label)
128
+ # Highlight the user's point
129
+ if user_sleep is not None and user_age is not None and user_cluster is not None:
130
+ color = colors[user_cluster % len(colors)]
131
+ ax2.scatter([user_sleep], [user_age], c='red', marker='*', s=250, edgecolors='black', linewidths=2, label='You')
132
+ ax2.set_xlabel('Sleep Hours per Night', fontweight='bold')
133
+ ax2.set_ylabel('Age', fontweight='bold')
134
+ ax2.set_title(f'Cluster Analysis: Sleep vs Age (k={optimal_k})', fontsize=12, fontweight='bold')
135
+ handles, labels = ax2.get_legend_handles_labels()
136
+ # Remove duplicate 'You' label if present
137
+ seen = set()
138
+ new_handles, new_labels = [], []
139
+ for h, l in zip(handles, labels):
140
+ if l not in seen:
141
+ new_handles.append(h)
142
+ new_labels.append(l)
143
+ seen.add(l)
144
+ ax2.legend(new_handles, new_labels)
145
+ ax2.grid(True, alpha=0.3)
146
+ plt.tight_layout()
147
+ img_buffer = io.BytesIO()
148
+ plt.savefig(img_buffer, format='png', dpi=300, bbox_inches='tight')
149
+ img_buffer.seek(0)
150
+ img_base64 = base64.b64encode(img_buffer.getvalue()).decode()
151
+ plt.close()
152
+ return f"data:image/png;base64,{img_base64}"