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

Matplotlib添加共享colorbar导致子图大小不等如何放置到右侧

问题描述

创建两个并排子图时需要使用公共共享colorbar,仅绘制一次colorbar,但按常规方式实现后两个子图会出现尺寸不等的问题,需要实现colorbar放置在所有子图右侧外部、且所有子图尺寸一致的效果。

子图大小不等问题示例

原有最小复现代码如下:

import numpy as np
from matplotlib import colors
import matplotlib.pyplot as plt

res = 100
x = np.linspace(0, 2*np.pi, res)

y = np.sin(x)
z = np.cos(x)
y2 = -np.sin(x)+0.4
z2 = 0.5*np.cos(2*x)

fig_width = 200/25.4                                                                                       
fig_height = 100/25.4                                                                                      
fig = plt.figure(figsize=(fig_width, fig_height))                                                          
gs = fig.add_gridspec(1, 2, wspace=0)                                                                      
(ax, ax2) = gs.subplots(sharey='row') 
images = []
images.append(ax.scatter(x, y, c=z))
images.append(ax2.scatter(x, y2, c=z2))
vmin = min(image.get_array().min() for image in images)
vmax = max(image.get_array().max() for image in images)
norm = colors.Normalize(vmin=vmin, vmax=vmax)
for im in images:
    im.set_norm(norm)
cbar = fig.colorbar(images[0], ax=ax2)
cbar.set_label("mylabel", loc='top')
fig.tight_layout()
plt.show()
问题原因

调用fig.colorbar()时如果仅传入单个子图作为ax参数,colorbar会挤占该单个子图的绘图空间,导致对应子图宽度被压缩,和其他子图尺寸不一致。

解决方案

给fig.colorbar()传入所有子图组成的列表作为ax参数,matplotlib会自动在所有子图的右侧外部预留统一的colorbar空间,不会单独压缩某一个子图;可通过pad参数调整colorbar和子图区域的间距,避免元素重叠。

修正后可直接运行的代码:

import numpy as np
from matplotlib import colors
import matplotlib.pyplot as plt

res = 100
x = np.linspace(0, 2*np.pi, res)

y = np.sin(x)
z = np.cos(x)
y2 = -np.sin(x)+0.4
z2 = 0.5*np.cos(2*x)

fig_width = 200/25.4                                                                                       
fig_height = 100/25.4                                                                                      
fig = plt.figure(figsize=(fig_width, fig_height))                                                          
gs = fig.add_gridspec(1, 2, wspace=0)                                                                      
(ax, ax2) = gs.subplots(sharey='row') 
images = []
images.append(ax.scatter(x, y, c=z))
images.append(ax2.scatter(x, y2, c=z2))
vmin = min(image.get_array().min() for image in images)
vmax = max(image.get_array().max() for image in images)
norm = colors.Normalize(vmin=vmin, vmax=vmax)
for im in images:
    im.set_norm(norm)
# 核心修改:传入所有子图对象列表作为ax参数,pad控制colorbar与子图间距
cbar = fig.colorbar(images[0], ax=[ax, ax2], pad=0.05)
cbar.set_label("mylabel", loc='top')
fig.tight_layout()
plt.show()
关键修改点
  • 将原代码中cbar = fig.colorbar(images[0], ax=ax2)的ax=ax2改为ax=[ax, ax2],告知matplotlib colorbar的放置参考为全部子图区域
  • 可选添加pad参数调整colorbar与子图区域的间距,数值越大间距越宽
  • 原有统一色标范围的Normalize逻辑无需改动,即可实现两个子图共用同一色阶
  • 该方法同样适用于多行多列子图的共享colorbar场景,只需将所有子图对象组成列表传入ax参数即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 03:03:39