| name | category-statistics |
| description | 提取指定类别列并统计各类别数量与占比,生成高分辨率的柱状图、饼图等组合可视化报告,适用于分类数据的分布情况分析。 |
Skill Steps
Step1 提取目标类别数据,清洗无效标签,并统计各类别数量与占比。
import pandas as pd
def calculate_distribution(data, target_col='类别'):
if target_col not in data.columns:
raise ValueError(f'未找到指定的类别字段: {target_col}')
category_data = data[target_col].dropna().replace(['--', '代码'], pd.NA).dropna()
counts = category_data.value_counts()
proportions = (counts / counts.sum()) * 100
return counts, proportions
Step2 生成基础可视化(双轴图:柱状图+占比曲线),并保存为高分辨率图片。
import matplotlib.pyplot as plt
def generate_and_save_basic_chart(counts, proportions, title='各类别数量分布', output_path='category_distribution.png'):
plt.rcParams['font.sans-serif'] = ['SimHei', 'WenQuanYi Zen Hei', 'Noto Sans CJK JP', 'DejaVu Sans']
plt.rcParams['axes.unicode_minus'] = False
fig, ax1 = plt.subplots(figsize=(10, 6))
bars = ax1.bar(counts.index, counts.values, color='skyblue', edgecolor='black')
for bar in bars:
height = bar.get_height()
ax1.text(bar.get_x() + bar.get_width()/2., height + 0.05, f'{height}', ha='center', va='bottom', fontsize=10)
ax1.set_ylabel('数量', fontsize=12)
ax1.set_title(title, fontsize=16, fontweight='bold', pad=20)
ax2 = ax1.twinx()
ax2.plot(counts.index, proportions.values, color='red', marker='o', linestyle='-', linewidth=2)
ax2.set_ylabel('占比 (%)', color='red', fontsize=12)
ax2.tick_params(axis='y', labelcolor='red')
plt.xticks(rotation=45)
plt.tight_layout()
fig.savefig(output_path, dpi=300, bbox_inches='tight')
plt.close(fig)
return output_path
Step3 生成多图组合报告(饼图+柱状图,以及带分类映射的水平柱状图),用于多维度展示。
import matplotlib.pyplot as plt
from matplotlib.patches import Patch
def generate_comprehensive_report(counts, proportions, output_dir='./'):
plt.rcParams['font.sans-serif'] = ['SimHei', 'WenQuanYi Zen Hei', 'Noto Sans CJK JP', 'DejaVu Sans']
plt.rcParams['axes.unicode_minus'] = False
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(15, 6))
colors = ['#ff9999', '#66b3ff', '#99ff99', '#ffcc99']
explode = [0.05] * len(counts) if len(counts) > 0 else None
wedges, texts, autotexts = ax1.pie(counts.values, labels=counts.index, autopct='%1.1f%%',
colors=colors[:len(counts)], explode=explode, shadow=True, startangle=90)
ax1.set_title('各类别比例分布', fontsize=14, fontweight='bold')
for autotext in autotexts:
autotext.set_color('white')
autotext.set_fontweight('bold')
bars = ax2.bar(range(len(counts)), counts.values, color=colors[:(counts)], alpha=, edgecolor=)
ax2.set_title(, fontsize=, fontweight=)
ax2.set_xticks(((counts)))
ax2.set_xticklabels(counts.index, rotation=, ha=)
i, bar (bars):
height = bar.get_height()
ax2.text(bar.get_x() + bar.get_width()/, height + , ,
ha=, va=, fontweight=)
plt.tight_layout()
pie_bar_path =
plt.savefig(pie_bar_path, dpi=, bbox_inches=)
plt.close(fig)
fig_h, ax_h = plt.subplots(figsize=(, ))
positions = [ i ((counts))]
bar_colors = [ (p) p counts.index]
bars_h = ax_h.barh(positions, counts.values, color=bar_colors, alpha=, edgecolor=)
ax_h.set_title(, fontsize=, fontweight=, pad=)
i, (bar, label) ((bars_h, counts.index)):
width = bar.get_width()
tag = (label)
ax_h.text(width + , bar.get_y() + bar.get_height()/, ,
ha=, va=, fontsize=)
legend_elements = [Patch(facecolor=, label=), Patch(facecolor=, label=)]
ax_h.legend(handles=legend_elements, loc=)
ax_h.grid(axis=, alpha=)
plt.tight_layout()
hbar_path =
plt.savefig(hbar_path, dpi=, bbox_inches=)
plt.close(fig_h)
[pie_bar_path, hbar_path]