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

Matplotlib多子图设置行标题及全图共用colorbar报错咨询

Matplotlib多子图行标题+全局共用colorbar实现方案

问题描述

需要实现Matplotlib多子图画布的两个核心效果:

  • 为每一行子图设置独立的行级标题
  • 为全图所有子图配置一个共用的colorbar
    实现过程中固定触发报错:

Unable to create a colorbar axes as not all parents share the same figure.

可复现报错的最小代码

import numpy as np
import matplotlib.pyplot as plt

datarow1 = [np.random.random((10, 10)), np.random.random((10, 10))]
datarow2 = [np.random.random((10, 10)), np.random.random((10, 10))]

fig = plt.figure(constrained_layout=True)
fig.suptitle('Main title', weight='bold', fontsize=20)
subfigs = fig.subfigures(2, 1)

subfigs[0].suptitle('Title row 1')
axesrow1 = subfigs[0].subplots(nrows=1, ncols=2)
axesrow1[0].imshow(datarow1[0], vmin=0, vmax=1, cmap='viridis')
axesrow1[1].imshow(datarow1[1], vmin=0, vmax=1, cmap='viridis')

subfigs[1].suptitle('Title row 2')
axesrow2 = subfigs[1].subplots(nrows=1, ncols=2)
axesrow2[0].imshow(datarow2[0], vmin=0, vmax=1, cmap='viridis')
axesrow2[1].imshow(datarow2[1], vmin=0, vmax=1, cmap='viridis')

fig.colorbar(plt.cm.ScalarMappable(cmap='viridis', norm=plt.Normalize(0, 1)), orientation='vertical', ax=fig.get_axes())

plt.show()

预期运行效果参考:
运行效果参考截图

报错根因

调用fig.subfigures()创建嵌套子画布后,fig.get_axes()返回的坐标轴列表包含子画布本身的容器级坐标轴,这些坐标轴分属不同的子父级画布,Matplotlib创建colorbar时校验到传入的坐标轴不共享同一个直接父对象,就会抛出该错误。

修正后可运行代码

只需要手动汇总所有实际绘图的子图坐标轴,替代fig.get_axes()传入colorbar的ax参数即可,原有行标题的实现逻辑不需要改动:

import numpy as np
import matplotlib.pyplot as plt

datarow1 = [np.random.random((10, 10)), np.random.random((10, 10))]
datarow2 = [np.random.random((10, 10)), np.random.random((10, 10))]

fig = plt.figure(constrained_layout=True)
fig.suptitle('Main title', weight='bold', fontsize=20)
subfigs = fig.subfigures(2, 1)

subfigs[0].suptitle('Title row 1')
axesrow1 = subfigs[0].subplots(nrows=1, ncols=2)
axesrow1[0].imshow(datarow1[0], vmin=0, vmax=1, cmap='viridis')
axesrow1[1].imshow(datarow1[1], vmin=0, vmax=1, cmap='viridis')

subfigs[1].suptitle('Title row 2')
axesrow2 = subfigs[1].subplots(nrows=1, ncols=2)
axesrow2[0].imshow(datarow2[0], vmin=0, vmax=1, cmap='viridis')
axesrow2[1].imshow(datarow2[1], vmin=0, vmax=1, cmap='viridis')

# 手动汇总所有实际绘图的子图坐标轴
all_plot_axes = list(axesrow1) + list(axesrow2)
fig.colorbar(
    plt.cm.ScalarMappable(cmap='viridis', norm=plt.Normalize(0, 1)),
    orientation='vertical',
    ax=all_plot_axes,
    fraction=0.02,  # 可选:调整colorbar宽度
    pad=0.02  # 可选:调整colorbar和子图的间距
)

plt.show()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 10:48:11