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

如何用Seaborn绘制以列名为分组元素的分组条形图?

问题:Seaborn绘制分组条形图是否需要转换数据?

我不确定能不能直接用Seaborn实现分组条形图(或catplot),核心需求是分组元素对应数据框的列名而非值。

给出的数据如下:

Year  Gin  Beer
0  2016   84    78
1  2017   75    30
2  2018   42    47
3  2019   25    58
4  2020   51    90
5  2021   40    50

期望的图表样式是按年份分组,每个年份对应Gin和Beer两个条形的分组条形图。

我尝试了以下代码,在y=参数中直接指定列名:

sns.catplot(data=a, x='Year', y=['Gin', 'Beer'])

请问是否无需修改数据就能实现该需求,还是必须对数据进行转换?

以下是最小可复现代码:

#!/usr/bin/env python3
import random as rd
import pandas as pd
from matplotlib import pyplot as plt
import seaborn as sns
sns.set_theme()

rd.seed(0)

a = pd.DataFrame({
    'Year': [2016, 2017, 2018, 2019, 2020, 2021],
    'Gin': rd.choices(range(100), k=6),
    'Beer': rd.choices(range(100), k=6)
})
print(a)

# sns.catplot(data=a, x='Year', y=['Gin', 'Beer'])
# plt.show()

解答

必须先转换数据,Seaborn的catplot(包括条形图类型)要求数据是长格式(long-form),而你当前的数据是宽格式(wide-form),直接传入多列作为y轴参数会报错。

你可以用pandas的melt方法快速转换数据格式:

# 将宽格式数据转换为长格式
df_long = a.melt(id_vars='Year', var_name='Drink', value_name='Amount')

# 绘制分组条形图
sns.catplot(data=df_long, x='Year', y='Amount', hue='Drink', kind='bar')
plt.show()

说明:

  • melt方法保留Year作为标识列,把Gin、Beer这类列名转换为Drink列的分类值,对应的数据值存入Amount列。
  • 转换后通过hue='Drink'参数区分不同饮品,就能实现你需要的分组条形图效果。

如果不想转换数据,只能用matplotlib的原生bar函数手动计算条形位置来绘制,但Seaborn的catplot系列函数不支持直接处理宽格式数据,这是由它的设计逻辑决定的。


内容的提问来源于stack exchange,提问作者buhtz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 10:20:17