如何绘制按DataFrame列分组的多个seaborn distplot并实现图表样式统一
分组分布绘图样式统一方案
核心问题排查
你的代码出现布局混乱、样式不统一的核心原因如下:
plt.show()放在for循环内部,每生成1张子图就单独渲染,导致gridspec全局布局完全失效- 未对所有子图统一配置轴范围、图例、刻度规则,不同特征的数值分布差异大导致观感不一致
- figsize与gridspec的比例不匹配,30行的子图设置
30*4的高度过高,会出现子图拉伸变形的问题 - 所用的
sns.distplot是seaborn已废弃的接口,参数兼容性差,容易出现异常样式
修正后可直接运行的代码
import seaborn as sns import matplotlib.pyplot as plt import matplotlib.gridspec as gridspec # 提前统一全局绘图样式,所有子图自动继承 sns.set_theme(style="whitegrid", font_scale=1.2) data_plot = creditcard_df.copy() amount = data_plot['Amount'] data_plot.drop(labels=['Amount'], axis=1, inplace = True) data_plot.insert(0, 'Amount', amount) # 取前30列特征 columns = data_plot.iloc[:,0:30].columns # 调整figsize为合理比例,30张子图总高度60即可,避免过度拉伸 plt.figure(figsize=(12, 60)) grids = gridspec.GridSpec(30, 1, hspace=0.8) # 统一设置子图垂直间距 for grid, col_name in enumerate(columns): ax = plt.subplot(grids[grid]) # 改用kdeplot,参数更可控 sns.kdeplot(data=data_plot[data_plot["Class"] == 1], x=col_name, fill=True, alpha=0.5, label="Class=1", ax=ax) sns.kdeplot(data=data_plot[data_plot["Class"] == 0], x=col_name, fill=True, alpha=0.5, label="Class=0", ax=ax) # 统一设置标题和X轴 ax.set_title(f"Distribution of Column: {col_name}", fontsize=10) ax.set_xlabel("") # 统一开启Y轴对数刻度,加判断避免数值全为0的报错 if ax.get_ylim()[1] > 0: ax.set_yscale("log") # 统一设置图例位置 ax.legend(loc="upper right", fontsize=8) # 所有子图生成完成后一次性渲染 plt.tight_layout() # 自动调整子图间距避免重叠 plt.show()
优化效果说明
以上修改后所有子图会自动保持样式统一:
- 所有图表的配色、字体、图例位置完全一致
- 开启Y轴对数刻度不会再出现布局混乱的问题
- 子图间距、拉伸比例统一,不会出现部分图压缩、部分图放大的情况
原错误输出参考:
内容的提问来源于stack exchange,提问作者ola
相关产品推荐
相关产品推荐

