如何让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
相关产品推荐
相关产品推荐

