如何用循环绘制多组同X异Y的Seaborn分组柱状图?
这问题我之前做项目时刚好遇到过,批量生成这类分组对比的柱状图其实用循环就能轻松搞定,我给你两种实用方案,按需选择:
方案1:逐个生成独立子图(简单直接)
这种方式会为每个Y轴变量单独生成一张图,适合需要单独查看每个指标对比的场景:
- 先确定要绘制的Y轴变量列表:你可以手动指定目标列,也可以自动筛选数据集中的数值列(排除
group列)。 - 循环遍历这个列表,每次调用
sns.catplot时替换y参数即可,还可以给每个图加上明确的标题。
import seaborn as sns import matplotlib.pyplot as plt # 方式1:手动指定需要对比的数值列(推荐,更精准) target_cols = ['Number of findings (total)', '列名1', '列名2', '列名3'] # 方式2:自动筛选所有数值列(排除group列) # target_cols = df.select_dtypes(include=['int64', 'float64']).columns # target_cols = target_cols[target_cols != 'group'] # 如果group是数值型才需要这步 # 循环绘制每个图 for col in target_cols: # 调用catplot生成柱状图 g = sns.catplot( x='group', y=col, kind="bar", palette="muted", data=df ) # 设置图标题,避免重叠可以调整y值 g.fig.suptitle(f'分组对比:{col}', y=1.02) # 显示当前图(脚本运行时需要,Jupyter环境可省略) plt.show()
方案2:整合为网格布局(方便批量对比)
如果想把所有对比图放在同一个画布上,方便同时查看多个指标的差异,可以结合Matplotlib的子图布局来实现:
import seaborn as sns import matplotlib.pyplot as plt # 同样先定义目标列 target_cols = ['Number of findings (total)', '列名1', '列名2', '列名3'] # 设置网格布局参数:每行放2个图,计算需要的行数 n_cols = 2 n_rows = (len(target_cols) + n_cols - 1) // n_cols # 创建画布和子图对象 fig, axes = plt.subplots(n_rows, n_cols, figsize=(14, 10)) # 把二维子图数组转成一维,方便循环遍历 axes = axes.flatten() # 循环绘制每个子图 for idx, col in enumerate(target_cols): ax = axes[idx] # 使用sns.barplot直接指定子图轴 sns.barplot( x='group', y=col, palette="muted", data=df, ax=ax ) # 设置子图标题和坐标轴标签 ax.set_title(f'{col}', fontsize=12) ax.set_xlabel('分组', fontsize=10) ax.set_ylabel(col, fontsize=10) # 隐藏多余的空轴(如果目标列数量不是列数的整数倍) for ax in axes[len(target_cols):]: ax.axis('off') # 自动调整子图间距,避免重叠 plt.tight_layout() plt.show()
小提示
- 如果你的列名比较长,可以用
ax.set_ylabel(col, rotation=45)来调整标签角度,避免重叠; - 可以根据需求修改
palette参数更换配色,比如"viridis"或者自定义颜色列表; - 如果需要添加统计显著性标记(比如p值),可以在循环里结合
scipy.stats计算后用ax.text()添加到图中。
内容的提问来源于stack exchange,提问作者Filippo Sebastio
相关产品推荐
相关产品推荐

