ai_member_xiaoxi/scripts/repeat_l1_l2_chart.py
2026-05-29 08:00:01 +08:00

90 lines
3.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import numpy as np
plt.rcParams['font.family'] = 'sans-serif'
for f in ['WenQuanYi Micro Hei', 'Noto Sans CJK SC', 'SimHei', 'DejaVu Sans']:
try:
plt.rcParams['font.sans-serif'] = [f]
break
except:
continue
plt.rcParams['axes.unicode_minus'] = False
# Data
l1 = {2:1887, 3:340, 4:91, 5:41, 6:7, 7:13, 8:4, 9:4, 10:2, 11:2, 12:1, 13:2, 19:1}
l2 = {2:2249, 3:313, 4:39, 5:10, 6:7, 7:4, 8:1, 9:1, 12:1, 14:1}
def group_5plus(d):
g = {'2次': d.get(2,0), '3次': d.get(3,0), '4次': d.get(4,0),
'5次': d.get(5,0), '6次+': sum(v for k,v in d.items() if k>=6)}
return g
l1g = group_5plus(l1)
l2g = group_5plus(l2)
cats = list(l1g.keys())
l1_vals = [l1g[c] for c in cats]
l2_vals = [l2g[c] for c in cats]
fig, axes = plt.subplots(1, 3, figsize=(18, 7))
# === Left: Side-by-side bar ===
x = np.arange(len(cats))
w = 0.35
bars1 = axes[0].bar(x - w/2, l1_vals, w, color='#4472C4', label='L1', edgecolor='white')
bars2 = axes[0].bar(x + w/2, l2_vals, w, color='#ED7D31', label='L2', edgecolor='white')
for bar in bars1:
h = bar.get_height()
if h > 0:
axes[0].text(bar.get_x()+bar.get_width()/2, h+max(l1_vals)*0.02, str(int(h)),
ha='center', fontsize=9, color='#4472C4')
for bar in bars2:
h = bar.get_height()
if h > 0:
axes[0].text(bar.get_x()+bar.get_width()/2, h+max(l2_vals)*0.02, str(int(h)),
ha='center', fontsize=9, color='#ED7D31')
axes[0].set_xticks(x)
axes[0].set_xticklabels(cats, fontsize=11)
axes[0].set_ylabel('重复学习组合数', fontsize=12)
axes[0].set_title('重复次数分布对比', fontsize=14, fontweight='bold')
axes[0].legend(fontsize=11)
axes[0].grid(axis='y', alpha=0.2, linestyle='--')
axes[0].set_ylim(0, max(max(l1_vals), max(l2_vals))*1.15)
# === Middle: L1 pie ===
l1_pie = [l1g[c] for c in cats]
l1_total = sum(l1_pie)
wedges1, _, autotexts1 = axes[1].pie(l1_pie, labels=None,
colors=['#4472C4','#5B9BD5','#9DC3E6','#BDD7EE','#D6E4F0'],
autopct='%1.1f%%', startangle=90, textprops={'fontsize': 10})
axes[1].set_title(f'L1 分布\n(951人, 2,395组合)', fontsize=14, fontweight='bold')
axes[1].legend(wedges1, [f'{c}: {v} ({v/l1_total*100:.1f}%)' for c,v in zip(cats, l1_pie)],
loc='lower center', fontsize=9)
# === Right: L2 pie ===
l2_pie = [l2g[c] for c in cats]
l2_total = sum(l2_pie)
wedges2, _, autotexts2 = axes[2].pie(l2_pie, labels=None,
colors=['#ED7D31','#F4B183','#F8CBAD','#FBE5D6','#F2F2F2'],
autopct='%1.1f%%', startangle=90, textprops={'fontsize': 10})
axes[2].set_title(f'L2 分布\n(397人, 2,626组合)', fontsize=14, fontweight='bold')
axes[2].legend(wedges2, [f'{c}: {v} ({v/l2_total*100:.1f}%)' for c,v in zip(cats, l2_pie)],
loc='lower center', fontsize=9)
fig.suptitle('最近3个月2026.03-05L1 vs L2 重复学习分布对比',
fontsize=16, fontweight='bold', y=1.02)
# Summary stats
fig.text(0.5, 0.01,
f'L1: 活跃7,280人, 重复951人(13.1%), 人均2.5组合, 最高19次 | '
f'L2: 活跃3,776人, 重复397人(10.5%), 人均6.6组合, 最高14次',
ha='center', fontsize=10, color='#555')
plt.tight_layout(rect=[0, 0.05, 1, 0.95])
plt.savefig('/root/.openclaw/workspace/output/repeat_l1_l2_3m.png', dpi=150, bbox_inches='tight')
print('Saved.')