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

如何让Matplotlib嵌套子图适配约束布局?

问题:Matplotlib嵌套子图启用约束布局报错AttributeError: 'Axes' object has no attribute 'rowspan'

我尝试在Matplotlib中创建嵌套子图,每个子图由接收axis对象的函数生成,部分绘图函数自身也能创建子图。

简单示例可正常运行:

def myplot(ax):
    gs = gridspec.GridSpecFromSubplotSpec(2, 1, subplot_spec=ax)
    fig = ax.figure
    ax1 = fig.add_subplot(gs[0, 0])
    ax1.plot([1, 3, 2])
    ax2 = fig.add_subplot(gs[1, 0])
    ax2.plot([1, 3, 2])

f, a = plt.subplot_mosaic("ab") 
myplot(a['a'])

但复杂图形中标签、刻度和图例会出现重叠问题,尝试用约束布局解决时,添加后抛出错误:

def myplot(ax):
    gs = gridspec.GridSpecFromSubplotSpec(2, 1, subplot_spec=ax)
    fig = ax.figure
    ax1 = fig.add_subplot(gs[0, 0])
    ax1.plot([1, 3, 2])
    ax2 = fig.add_subplot(gs[1, 0])
    ax2.plot([1, 3, 2])

f, a = plt.subplot_mosaic("ab")
f.set_constrained_layout(True)
myplot(a['a'])

报错信息:

AttributeError: 'Axes' object has no attribute 'rowspan'

解决方案

错误原因

GridSpecFromSubplotSpec需要传入**SubplotSpec对象**来定义嵌套子图的布局,但subplot_mosaic返回的a['a']是Axes实例。约束布局在处理时会尝试访问SubplotSpec特有的rowspan/colspan属性,而Axes对象没有这些属性,因此触发报错。

修复方法1:传入SubplotSpec而非Axes

直接获取subplot_mosaic对应位置的SubplotSpec,传入绘图函数,并移除原有的Axes避免重叠:

import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec

def myplot(spec):
    # 基于SubplotSpec创建嵌套网格
    gs = gridspec.GridSpecFromSubplotSpec(2, 1, subplot_spec=spec)
    fig = spec.figure
    # 移除原位置的Axes
    spec.get_axes()[0].remove()
    # 创建嵌套子图
    ax1 = fig.add_subplot(gs[0])
    ax1.plot([1, 3, 2])
    ax2 = fig.add_subplot(gs[1])
    ax2.plot([1, 3, 2])

# 启用约束布局创建画布
f = plt.figure(constrained_layout=True)
# 创建mosaic布局
f.subplot_mosaic("ab")
# 获取"a"位置对应的SubplotSpec
spec_a = f._gridspec.get_subplot_spec((0, 0))
myplot(spec_a)

plt.show()

修复方法2:利用subplot_mosaic的嵌套语法

直接在subplot_mosaic的布局定义中声明嵌套结构,让Matplotlib自动处理约束布局,无需手动创建GridSpec:

import matplotlib.pyplot as plt

def myplot(axs):
    axs[0].plot([1, 3, 2])
    axs[1].plot([1, 3, 2])

# 定义嵌套mosaic:"a"位置跨2行,"b"位置对应右侧列
f, ax_dict = plt.subplot_mosaic(
    [['a', 'b'], ['a', 'b']],
    constrained_layout=True
)
# ax_dict['a']是包含两个Axes的数组,直接传入绘图函数
myplot(ax_dict['a'])

plt.show()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 15:20:16