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

matplotlib中GridSpec搭配constrained_layout警告的解决方法

问题背景

在PyCharm开发环境下使用Python的matplotlib库绘制自定义网格布局的可视化图表,目标为3行3列网格的自定义子图排布,初始实现代码如下:

import matplotlib.pyplot as plt
from matplotlib.gridspec import GridSpec


def format_axes(fig):
    for i, ax in enumerate(fig.axes):
        ax.text(0.5, 0.5, "ax%d" % (i+1), va="center", ha="center")
        ax.tick_params(labelbottom=False, labelleft=False)

fig = plt.figure(constrained_layout=True)

gs = GridSpec(3, 3, figure=fig)
ax1 = fig.add_subplot(gs[:2, 0])
ax2 = fig.add_subplot(gs[:2, 1:])
ax3 = fig.add_subplot(gs[-1, 1:])

fig.suptitle("GridSpec")
format_axes(fig)

plt.show()

运行代码时抛出警告:

UserWarning: constrained_layout not applied. At least one axes collapsed to zero width or height.
无法正常得到预期布局效果。

问题原因

警告触发的核心原因是:定义的3行3列GridSpec网格中,第三行第0列(索引为(2,0))的网格单元没有分配任何子图,开启constrained_layout自动布局时,算法会将无内容关联的网格单元宽高计算为0,导致布局计算失败抛出警告。

解决方法

两种方案均可消除警告,得到预期布局:

方案1:替换自动布局方案

移除figure创建时的constrained_layout=True参数,在所有子图创建完成后调用tight_layout()完成布局调整,通过rect参数为顶部总标题预留显示空间,修改后可直接运行的代码如下:

import matplotlib.pyplot as plt
from matplotlib.gridspec import GridSpec


def format_axes(fig):
    for i, ax in enumerate(fig.axes):
        ax.text(0.5, 0.5, "ax%d" % (i+1), va="center", ha="center")
        ax.tick_params(labelbottom=False, labelleft=False)

# 移除constrained_layout参数,可按需设置画布尺寸
fig = plt.figure(figsize=(8, 6))

gs = GridSpec(3, 3, figure=fig)
ax1 = fig.add_subplot(gs[:2, 0])
ax2 = fig.add_subplot(gs[:2, 1:])
ax3 = fig.add_subplot(gs[-1, 1:])

fig.suptitle("GridSpec")
format_axes(fig)
# rect参数格式为[左边界, 下边界, 右边界, 上边界],留出顶部4%空间放标题
plt.tight_layout(rect=[0, 0, 1, 0.96])

plt.show()

方案2:保留constrained_layout,添加占位轴

如果需要使用constrained_layout的布局特性,可以给未分配的空网格单元创建一个隐藏的占位轴,让布局算法可以正常计算所有网格单元的尺寸,修改后代码如下:

import matplotlib.pyplot as plt
from matplotlib.gridspec import GridSpec


def format_axes(fig):
    for i, ax in enumerate(fig.axes):
        # 跳过隐藏的占位轴,不做文本标注
        if not ax.get_visible():
            continue
        ax.text(0.5, 0.5, "ax%d" % (i+1), va="center", ha="center")
        ax.tick_params(labelbottom=False, labelleft=False)

# 保留constrained_layout配置
fig = plt.figure(constrained_layout=True, figsize=(8, 6))

gs = GridSpec(3, 3, figure=fig)
ax1 = fig.add_subplot(gs[:2, 0])
ax2 = fig.add_subplot(gs[:2, 1:])
ax3 = fig.add_subplot(gs[-1, 1:])
# 创建空位置的占位轴并设置为不可见
ax_placeholder = fig.add_subplot(gs[-1, 0])
ax_placeholder.set_visible(False)

fig.suptitle("GridSpec")
format_axes(fig)

plt.show()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 05:12:19