根本原因是subplots_adjust()未作用于目标figure:若用plt.subplots(),须调用fig.subplots_adjust();若误调plt.figure()会创建新空白图,导致调整无效。

为什么 plt.subplots_adjust() 调了没反应?
常见现象是调用 plt.subplots_adjust(left=0.1, right=0.9) 后,子图位置看起来完全没变。根本原因通常是:你用了 plt.subplot() 或手动创建了 Figure 和 Axes,但没把调整作用到目标 Figure 实例上。
更隐蔽的情况是:你在 plt.subplots() 之后又调用了 plt.figure() —— 这会新建一个 Figure,后续的 subplots_adjust() 默认操作的是这个新空白图,而非你画图的那个。
- 务必确认
subplots_adjust()在绘图之后、plt.show()之前调用 - 如果用
fig, axes = plt.subplots(2, 2),优先用fig.subplots_adjust(...),它比全局plt.subplots_adjust()更可靠 - 检查是否意外触发了自动布局(如启用了
plt.rcParams['figure.autolayout'] = True),它会覆盖你的手动调整
用 fig.subplots_adjust() 控制上下左右边距
这是最稳妥的方式,明确绑定到当前 figure,避免全局污染和作用对象错位。
-
left:左边界到最左子图左边的距离(归一化值,0–1);设为0.15比默认0.125更宽松,防标签被截 -
right:最右子图右边到右边界距离;若右侧 colorbar 被切,试试right=0.85 -
bottom和top同理,尤其当 x 轴标签或标题过长时,bottom=0.12常比默认0.11更安全 - 四个参数可同时设:
fig.subplots_adjust(left=0.12, bottom=0.12, right=0.9, top=0.88, wspace=0.3, hspace=0.4)
fig, axes = plt.subplots(2, 3) # 绘图代码... fig.subplots_adjust(wspace=0.4, hspace=0.3) # 列间距加大,行间距略紧
wspace 和 hspace 不是像素,是子图宽度/高度的比例
这两个参数常被误解为“像素间隔”,实际是相对于子图自身宽度(wspace)或高度(hspace)的倍数。比如 wspace=0.2 表示列间空隙 = 0.2 × 单个子图的宽度。
- 值太小(如
0.05)会导致相邻子图的 y 轴标签重叠 - 值太大(如
0.8)会让图面稀疏,尤其在小尺寸 figure 中更明显 - 当子图宽高比差异大(如有的图是横向直方图,有的是正方形热力图),
wspace/hspace的视觉效果会不一致——这时应优先考虑constrained_layout=True或GridSpec - 注意:它只影响由
plt.subplots()创建的规则网格;对add_subplot()手动添加的子图无效
替代方案:什么时候该放弃 subplots_adjust?
当你反复调参仍无法兼顾标题、colorbar、共享轴标签和紧凑排布时,说明问题已超出 subplots_adjust 的能力边界。
- 有 colorbar 且要靠右对齐 → 用
plt.colorbar(..., ax=ax, shrink=0.6)+fig.tight_layout(rect=[0,0,0.85,1]) - 需要不等宽子图(如左侧主图 + 右侧窄参数栏)→ 直接上
GridSpec,它支持行列权重和跨格 - 多行标题 + 共享 x/y 标签 + 子图内嵌小图 → 开启
constrained_layout=True(matplotlib ≥ 3.3),它自动求解约束,比手调更鲁棒 - 导出 PDF/PNG 时发现字体大小与间距失配 → 在
plt.savefig()中显式传入bbox_inches='tight',它会二次裁剪外边距
真正难调的不是参数本身,而是没意识到:子图间距从来不是孤立问题——它和字体大小、figure 尺寸、label 长度、是否共享坐标轴全绑在一起。改一个,往往得同步看三个。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











