You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 21:47:03