如何用Matplotlib/Seaborn绘制DataFrame分组条形图(类别为行)
用Matplotlib/Seaborn绘制分类指标分组条形图
我有一个存储分类指标分数的DataFrame,列对应精确率、召回率、F1分数、样本数等指标,行代表愤怒、困惑、好奇等不同情感类别。目标是绘制分组条形图:x轴为各类别,y轴为指标分数,用不同颜色区分指标类型。下面提供两种实现方案:
示例DataFrame结构
精确率 召回率 F1分数 样本数 愤怒 0.6374 0.150138 0.243032 726.0 困惑 0.1666 0.006536 0.012579 153.0 好奇 0.3333 0.003521 0.006969 284.0 渴望 0.8750 0.084337 0.153846 83.0 厌恶 0.6250 0.040650 0.076336 123.0 尴尬 0.0000 0.000000 0.000000 37.0 恐惧 0.6666 0.020408 0.039604 98.0 喜悦 0.7039 0.354877 0.471875 851.0 爱意 0.8285 0.573657 0.677931 1154.0 中性 0.5394 0.371013 0.439655 1787.0 乐观 0.7704 0.252688 0.380567 186.0 自豪 0.0000 0.000000 0.000000 16.0 悲伤 0.7165 0.240106 0.359684 379.0 惊讶 0.6956 0.057554 0.106312 278.0 微平均 0.6648 0.309667 0.422523 6155.0 宏平均 0.5399 0.153963 0.212028 6155.0 加权平均 0.6377 0.309667 0.391975 6155.0 样本平均 0.3404 0.324519 0.327904 6155.0
方法一:Matplotlib手动实现分组条形图
Matplotlib需要手动计算条形位置,灵活性更强:
import matplotlib.pyplot as plt import pandas as pd # 构造与示例一致的DataFrame data = { "精确率": [0.6374, 0.1666, 0.3333, 0.8750, 0.6250, 0.0000, 0.6666, 0.7039, 0.8285, 0.5394, 0.7704, 0.0000, 0.7165, 0.6956, 0.6648, 0.5399, 0.6377, 0.3404], "召回率": [0.150138, 0.006536, 0.003521, 0.084337, 0.040650, 0.000000, 0.020408, 0.354877, 0.573657, 0.371013, 0.252688, 0.000000, 0.240106, 0.057554, 0.309667, 0.153963, 0.309667, 0.324519], "F1分数": [0.243032, 0.012579, 0.006969, 0.153846, 0.076336, 0.000000, 0.039604, 0.471875, 0.677931, 0.439655, 0.380567, 0.000000, 0.359684, 0.106312, 0.422523, 0.212028, 0.391975, 0.327904], "样本数": [726.0, 153.0, 284.0, 83.0, 123.0, 37.0, 98.0, 851.0, 1154.0, 1787.0, 186.0, 16.0, 379.0, 278.0, 6155.0, 6155.0, 6155.0, 6155.0] } categories = ["愤怒", "困惑", "好奇", "渴望", "厌恶", "尴尬", "恐惧", "喜悦", "爱意", "中性", "乐观", "自豪", "悲伤", "惊讶", "微平均", "宏平均", "加权平均", "样本平均"] df = pd.DataFrame(data, index=categories) # 选择要可视化的指标(排除样本数,因数值量级差异过大) metrics = ["精确率", "召回率", "F1分数"] n_metrics = len(metrics) n_cats = len(df.index) # 设置条形宽度,控制分组间距 bar_width = 0.25 # 生成基础x轴位置 x = range(n_cats) # 创建画布,调整尺寸适配长类别名称 plt.figure(figsize=(16, 8)) # 循环绘制每个指标的条形 for idx, metric in enumerate(metrics): # 计算当前指标条形的x位置 bar_pos = [pos + bar_width * idx for pos in x] plt.bar(bar_pos, df[metric], width=bar_width, label=metric) # 设置x轴标签,居中对齐分组条形 plt.xticks([pos + bar_width*(n_metrics-1)/2 for pos in x], df.index, rotation=45, ha="right") # 添加标题和轴标签 plt.title("各情感类别的分类指标对比", fontsize=14) plt.xlabel("情感类别", fontsize=12) plt.ylabel("指标分数", fontsize=12) # 添加图例 plt.legend() # 自动调整布局,避免标签被截断 plt.tight_layout() plt.show()
方法二:Seaborn快速实现分组条形图
Seaborn更适合处理这类统计可视化,只需将DataFrame转为长格式即可:
import seaborn as sns import matplotlib.pyplot as plt import pandas as pd # 构造示例DataFrame data = { "精确率": [0.6374, 0.1666, 0.3333, 0.8750, 0.6250, 0.0000, 0.6666, 0.7039, 0.8285, 0.5394, 0.7704, 0.0000, 0.7165, 0.6956, 0.6648, 0.5399, 0.6377, 0.3404], "召回率": [0.150138, 0.006536, 0.003521, 0.084337, 0.040650, 0.000000, 0.020408, 0.354877, 0.573657, 0.371013, 0.252688, 0.000000, 0.240106, 0.057554, 0.309667, 0.153963, 0.309667, 0.324519], "F1分数": [0.243032, 0.012579, 0.006969, 0.153846, 0.076336, 0.000000, 0.039604, 0.471875, 0.677931, 0.439655, 0.380567, 0.000000, 0.359684, 0.106312, 0.422523, 0.212028, 0.391975, 0.327904], "样本数": [726.0, 153.0, 284.0, 83.0, 123.0, 37.0, 98.0, 851.0, 1154.0, 1787.0, 186.0, 16.0, 379.0, 278.0, 6155.0, 6155.0, 6155.0, 6155.0] } categories = ["愤怒", "困惑", "好奇", "渴望", "厌恶", "尴尬", "恐惧", "喜悦", "爱意", "中性", "乐观", "自豪", "悲伤", "惊讶", "微平均", "宏平均", "加权平均", "样本平均"] df = pd.DataFrame(data, index=categories) # 将宽格式DataFrame转为长格式,排除样本数列 df_long = df.drop("样本数", axis=1).reset_index() df_long = df_long.melt(id_vars="index", var_name="指标", value_name="分数") df_long.rename(columns={"index": "情感类别"}, inplace=True) # 设置Seaborn可视化样式 sns.set_style("whitegrid") # 创建画布 plt.figure(figsize=(16, 8)) # 绘制分组条形图,hue参数区分不同指标 sns.barplot(x="情感类别", y="分数", hue="指标", data=df_long) # 设置标题和轴标签 plt.title("各情感类别的分类指标对比", fontsize=14) plt.xlabel("情感类别", fontsize=12) plt.ylabel("指标分数", fontsize=12) # 旋转x轴标签,避免重叠 plt.xticks(rotation=45, ha="right") # 调整布局 plt.tight_layout() plt.show()
注意事项
- 如果需要展示
样本数,建议单独绘制双y轴图表或分开可视化,因为它的数值量级远高于其他指标,同图展示会压缩指标分数的视觉差异。 - 可根据需求调整画布大小、颜色主题(如
sns.set_palette())、标签旋转角度等,提升图表可读性。
内容的提问来源于stack exchange,提问作者WIsh Suharitdamrong
相关产品推荐
相关产品推荐

