如何在Seaborn多子图绘制中单独设置各子图的尺寸占比?
自定义Seaborn子图尺寸比例实现方案
核心结论
完全可以实现目标效果。默认plt.subplots(1,2)创建的横向双列子图会平均分配画布宽度,只要在创建子图网格时显式指定宽度比例,就能让热图占总宽度的75%、条形图仅占25%,不需要改动后续的Seaborn绘图逻辑。
最简实现方法
调用plt.subplots时通过gridspec_kw参数传入width_ratios配置,设置两个子图的宽度比例为3:1(对应75%:25%)即可:
import numpy as np import matplotlib.pyplot as plt import seaborn as sns # 创建子图,指定宽度比例 fig, ax = plt.subplots( 1, 2, figsize=(7, 5), gridspec_kw={"width_ratios": [3, 1]} # 左热图:右条形图 = 3:1 宽度占比 ) # 统一变量名,修正原代码中的笔误 heatmap_scores = np.random.uniform(0, 1, size=(12, 12)) sns.heatmap(heatmap_scores, linewidth=0.5, cmap="OrRd", ax=ax[0]) ax[0].set_xlabel('Head') ax[0].set_ylabel('Layer') ax[0].set_title('Attention Heatmap') x = np.mean(heatmap_scores, axis=1) y = np.arange(0, 12) sns.barplot(x=x, y=y, ax=ax[1], orient='h', color='r', dodge=False) ax[1].set_title('Layer Average') ax[1].set(yticklabels=[]) plt.tight_layout() # 自动修正子图边距,避免标题、标签重叠 plt.savefig('fig.png') plt.close()
灵活排版方案(适配复杂场景)
如果后续需要调整子图间距、跨列绘制等更复杂的布局,可以直接使用Matplotlib的GridSpec模块自定义网格规则:
fig = plt.figure(figsize=(7, 5)) # 定义1行2列网格,宽度占比3:1 gs = fig.add_gridspec(1, 2, width_ratios=[3, 1]) # 分别绑定两个坐标轴 ax_heatmap = fig.add_subplot(gs[0, 0]) ax_bar = fig.add_subplot(gs[0, 1]) # 后续绘图逻辑与原代码完全一致,将对应坐标轴传入Seaborn接口即可
注意事项
- 宽度比例支持任意数值,不一定非要凑整数,直接写
width_ratios=[0.75, 0.25]也能实现完全相同的分配效果。 - 原参考代码存在两处可运行性问题需要修正:
- 第一行子图创建语句的
ig, ax为输入笔误,需修正为fig, ax - 前面生成的热图数组变量名与后续绘图引用的
heatmap_scores不匹配,需统一变量名避免运行报错
- 第一行子图创建语句的
内容的提问来源于stack exchange,提问作者user3480922
相关产品推荐
相关产品推荐

