Spaces:
Runtime error
Runtime error
File size: 8,448 Bytes
ae06fdb 925e69c ae06fdb 925e69c ae06fdb 925e69c ae06fdb 925e69c ae06fdb 925e69c ae06fdb 925e69c ae06fdb 925e69c ae06fdb 496f017 ae06fdb 496f017 ae06fdb 496f017 223798c ae06fdb b5127dd ae06fdb 0e6d93f b5127dd ae06fdb 0e6d93f ae06fdb 223798c |
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 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
import matplotlib.pyplot as plt
import numpy as np
import io
import base64
# Pie chart for conflict prediction
def create_conflict_pie_chart(result):
fig, ax = plt.subplots(figsize=(3, 2))
# Handle missing confidence
if 'confidence' in result and result['confidence'] is not None:
confidence = result['confidence']
else:
confidence = 0.8 # Default confidence when not available
if result['conflict_level'] == 'High Risk':
colors = ['#ff6b6b', '#4ecdc4']
sizes = [confidence, 1 - confidence]
labels = ['High Risk', 'Low Risk']
else:
colors = ['#4ecdc4', '#ff6b6b']
sizes = [confidence, 1 - confidence]
labels = ['Low Risk', 'High Risk']
wedges, texts, autotexts = ax.pie(sizes, labels=labels, colors=colors, autopct='%1.1f%%',
startangle=90, explode=(0.1, 0))
# Update title to handle missing confidence
if 'confidence' in result and result['confidence'] is not None:
title = f'Conflict Risk Prediction\nConfidence: {confidence:.1%}'
else:
title = f'Conflict Risk Prediction\nConfidence: {confidence:.1%} (estimated)'
ax.set_title(title, fontsize=10, fontweight='bold', pad=10)
for autotext in autotexts:
autotext.set_color('white')
autotext.set_fontweight('bold')
ax.legend(wedges, labels, title="Risk Levels", loc="center left", bbox_to_anchor=(1, 0, 0.5, 1))
plt.tight_layout()
img_buffer = io.BytesIO()
plt.savefig(img_buffer, format='png', dpi=300, bbox_inches='tight')
img_buffer.seek(0)
img_base64 = base64.b64encode(img_buffer.getvalue()).decode()
plt.close()
return f"data:image/png;base64,{img_base64}"
# Histogram for addiction score (not currently used, but included for completeness)
def create_addiction_score_chart(result, data=None):
fig, ax = plt.subplots(figsize=(3, 2))
if data is not None and 'Addicted_Score' in data.columns:
scores = data['Addicted_Score'].dropna()
else:
np.random.seed(42)
scores = np.random.normal(5.5, 1.5, 1000)
scores = np.clip(scores, 1, 10)
n, bins, patches = ax.hist(scores, bins=20, alpha=0.7, color='#4ecdc4',
edgecolor='black', linewidth=0.5)
predicted_score = result['predicted_score']
ax.axvline(x=predicted_score, color='#ff6b6b', linewidth=3,
label=f'Your Prediction: {predicted_score:.2f}')
if 'confidence' in result:
confidence = result['confidence']
ax.axvspan(predicted_score - 0.5, predicted_score + 0.5,
alpha=0.3, color='#ff6b6b',
label=f'Confidence: {confidence:.2f}')
ax.set_title('Addiction Score Distribution with Your Prediction',
fontsize=10, fontweight='bold', pad=10)
ax.set_xlabel('Addiction Score (1-10)', fontsize=8, fontweight='bold')
ax.set_ylabel('Frequency', fontsize=8, fontweight='bold')
ax.axvspan(1, 3, alpha=0.2, color='green', label='Low Addiction (1-3)')
ax.axvspan(3, 7, alpha=0.2, color='orange', label='Moderate Addiction (3-7)')
ax.axvspan(7, 10, alpha=0.2, color='red', label='High Addiction (7-10)')
ax.legend(loc='upper right', fontsize=7)
ax.grid(True, alpha=0.3)
ax.set_xlim(0, 10)
plt.tight_layout()
img_buffer = io.BytesIO()
plt.savefig(img_buffer, format='png', dpi=300, bbox_inches='tight')
img_buffer.seek(0)
img_base64 = base64.b64encode(img_buffer.getvalue()).decode()
plt.close()
return f"data:image/png;base64,{img_base64}"
# Gauge chart for addiction score
def create_addiction_gauge_chart(result):
fig, ax = plt.subplots(figsize=(3, 2), subplot_kw={'projection': 'polar'})
predicted_score = result['predicted_score']
angle = (predicted_score - 1) * 20
theta = np.linspace(0, np.pi, 100)
# Reduce black line thickness by 30% (from 3 to 2.1)
ax.plot(theta, [1]*100, 'k-', linewidth=2.1)
# Flip colors over y-axis - now high scores are on the left (0) and low scores on the right (pi)
high_angle = np.linspace(0, 2*20*np.pi/180, 50)
ax.fill_between(high_angle, 0, 1, alpha=0.3, color='red', label='High (7-10)')
mod_angle = np.linspace(2*20*np.pi/180, 6*20*np.pi/180, 50)
ax.fill_between(mod_angle, 0, 1, alpha=0.3, color='orange', label='Moderate (3-7)')
low_angle = np.linspace(6*20*np.pi/180, np.pi, 50)
ax.fill_between(low_angle, 0, 1, alpha=0.3, color='green', label='Low (1-3)')
needle_angle = angle * np.pi / 180
# Reduce needle line thickness by 30% (from 4 to 2.8)
ax.plot([needle_angle, needle_angle], [0, 1.2], 'k-', linewidth=2.8, label=f'Your Score: {predicted_score:.1f}')
# Reduce round dot size by 50% (from 10 to 5)
ax.plot(needle_angle, 1.2, 'ko', markersize=5, markeredgecolor='white', markeredgewidth=2)
ax.set_title(f'Addiction Score Gauge\nPredicted: {predicted_score:.1f}/10',
fontsize=8, fontweight='bold', pad=10)
ax.set_xticks([])
ax.set_yticks([])
ax.set_ylim(0, 1.3)
# Flip the gauge by adjusting text positions and angles
ax.text(np.pi, 1.4, 'Low\n(1-3)', ha='center', va='center', fontsize=3, fontweight='bold')
ax.text(np.pi/2, 1.4, 'Moderate\n(3-7)', ha='center', va='center', fontsize=3, fontweight='bold')
ax.text(0, 1.4, 'High\n(7-10)', ha='center', va='center', fontsize=3, fontweight='bold')
if 'confidence' in result:
confidence = result['confidence']
ax.text(0, -0.3, f'Confidence: {confidence:.2f}', ha='center', va='center',
fontsize=6, fontweight='bold', bbox=dict(boxstyle="round,pad=0.3", facecolor="lightblue"))
plt.tight_layout()
img_buffer = io.BytesIO()
plt.savefig(img_buffer, format='png', dpi=300, bbox_inches='tight')
img_buffer.seek(0)
img_base64 = base64.b64encode(img_buffer.getvalue()).decode()
plt.close()
return f"data:image/png;base64,{img_base64}"
# Clustering: Elbow and Sleep vs Age scatter plot
def create_clustering_charts(result, cluster_df=None, user_sleep=None, user_age=None, user_cluster=None, cluster_labels_map=None):
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
optimal_k = 3
k_values = range(1, 11)
inertias = [150, 120, 85, 65, 55, 50, 47, 45, 43, 42]
ax1.plot(k_values, inertias, 'bo-', linewidth=2, markersize=8)
ax1.set_xlabel('Number of Clusters (k)', fontweight='bold')
ax1.set_ylabel('Inertia', fontweight='bold')
ax1.set_title('Elbow Method: Optimal K Selection', fontsize=12, fontweight='bold')
ax1.grid(True, alpha=0.3)
ax1.axvline(x=optimal_k, color='red', linestyle='--', alpha=0.7, label=f'Optimal k = {optimal_k}')
ax1.legend()
# Scatter plot: Sleep vs Age colored by cluster (always 3 clusters/colors)
if cluster_df is not None and cluster_labels_map is not None:
colors = ['#4ecdc4', '#ffd93d', '#ff6b6b']
for cluster in range(optimal_k):
sub = cluster_df[cluster_df['cluster'] == cluster]
color = colors[cluster % len(colors)]
label = cluster_labels_map.get(cluster, f'Cluster {cluster}')
ax2.scatter(sub['Sleep_Hours_Per_Night'], sub['Age'], c=color, alpha=0.7, s=50, label=label)
# Highlight the user's point
if user_sleep is not None and user_age is not None and user_cluster is not None:
color = colors[user_cluster % len(colors)]
ax2.scatter([user_sleep], [user_age], c='red', marker='*', s=250, edgecolors='black', linewidths=2, label='You')
ax2.set_xlabel('Sleep Hours per Night', fontweight='bold')
ax2.set_ylabel('Age', fontweight='bold')
ax2.set_title(f'Cluster Analysis: Sleep vs Age (k={optimal_k})', fontsize=12, fontweight='bold')
handles, labels = ax2.get_legend_handles_labels()
# Remove duplicate 'You' label if present
seen = set()
new_handles, new_labels = [], []
for h, l in zip(handles, labels):
if l not in seen:
new_handles.append(h)
new_labels.append(l)
seen.add(l)
ax2.legend(new_handles, new_labels)
ax2.grid(True, alpha=0.3)
plt.tight_layout()
img_buffer = io.BytesIO()
plt.savefig(img_buffer, format='png', dpi=300, bbox_inches='tight')
img_buffer.seek(0)
img_base64 = base64.b64encode(img_buffer.getvalue()).decode()
plt.close()
return f"data:image/png;base64,{img_base64}" |