You need to enable JavaScript to run this app. Matplotlib多imshow子图colorbar范围统一与位置调整实现
优惠活动
大模型
产品
解决方案
定价
更多

Matplotlib多imshow子图colorbar范围统一与位置调整实现

问题核心修复方案

1. 实现同组子图色标映射统一

同组色标不统一的核心原因是代码在循环内为每张子图单独创建LogNorm()实例,每个norm会自动适配当前子图的数值范围生成独立的色阶映射,后续单独修改colorbar的clim仅能作用于最后一次循环生成的mappable,无法同步所有同组子图。
修复方式:

  • 提前为两组数据分别固定数值范围,创建全局共享的norm实例
  • 所有同组的imshow调用都传入这个共享的norm,从根源上保证数值到颜色的映射规则完全一致
  • 不需要后续对colorbar单独设置clim,因为固定的norm会同步所有子图和colorbar的映射范围

2. 实现第二组colorbar在后两列上方水平居中

原代码仅将第一行的两个轴作为colorbar的依附对象,无法锚定整组列的总宽度范围,容易出现位置偏移。
修复方式:

  • 给colorbar的ax参数传入对应列组的所有行轴对象,而非仅第一行的轴
  • matplotlib会自动计算整组轴的包围盒,将顶部放置的colorbar调整为与整组轴等宽,自然实现水平居中对齐
  • 调整合理的pad参数,避免colorbar过近压到子图内容

附带修复的原代码bug

  • 索引越界:原代码定义的cm = ['hot', 'viridis']仅包含2个元素(索引0、1),但实际调用时使用了cm[2],会触发数组越界报错,需修正为cm[1]
  • 变量覆盖:原代码在循环内重复对外部列表类型的data变量重新赋值,会覆盖原有预设的分类列表,需调整内部变量名避免混淆

修正后的可运行测试代码

import matplotlib.pyplot as plt
import matplotlib as mpl
import numpy as np  # 用于生成测试随机矩阵

a = 5
b = 4
fig, axs = plt.subplots(a, b , figsize=(8.27, 11.69), tight_layout=True, sharey=True, sharex=True, gridspec_kw = {'wspace':0, 'hspace':0})

gasf = ['fg10', 'fg20', 'fg30', 'fg50', 'fg70']
dire = ['x', 'z', 'x', 'z']
cm = ['hot', 'viridis']

# 提前定义共享的固定范围的norm,实现同组色标统一
norm_sm = mpl.colors.LogNorm(vmin=1E2, vmax=1E9)
norm_dens = mpl.colors.LogNorm(vmin=1E-5, vmax=1E0)

# 生成测试用随机矩阵替换eval(data)的逻辑
test_data_sm = np.random.uniform(low=1E2, high=1E9, size=(100,100))
test_data_dens = np.random.uniform(low=1E-5, high=1E0, size=(100,100))

for col in range(b):
    for row in range(a):
        ax = axs[row, col]
        if col ==0:
            ax.set_ylabel('x (kpc)', fontsize=13)
        if col < 2:
            # 所有sm组的图都使用同一个共享norm
            pcm = ax.imshow(test_data_sm,  norm=norm_sm, cmap=cm[0], interpolation='none', extent=[-17.5,17.5,-17.5,17.5])
        else:
            # 所有dens组的图都使用同一个共享norm,修正原cm[2]的越界问题
            pcm2 = ax.imshow(test_data_dens, norm=norm_dens, cmap=cm[1], interpolation='none', extent=[-17.5,17.5,-17.5,17.5])
        if row ==4:
            if col == 0:
                ax.set_xlabel('z (kpc)',  fontsize=13)
            if col == 1:
                ax.set_xlabel('y (kpc)', fontsize=13)
            if col == 2:
                ax.set_xlabel('z (kpc)', fontsize=13)
            if col == 3:
                ax.set_xlabel('y (kpc)', fontsize=13)

# colorbar传入整列组的所有轴对象,自动实现水平居中,调整合理pad值
cb1 = fig.colorbar(pcm, ax=axs[:, :2], location='top', pad=0.15)
cb2 = fig.colorbar(pcm2, ax=axs[:, 2:4], location='top', pad=0.15)

plt.show()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.01 20:24:10