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

如何在Python Matplotlib中修正带Colorbar的子图尺寸:解决3×2子图第三行图像缩小问题

解决3×2子图中带Colorbar行的图像尺寸不一致问题

这个问题的核心原因很明确:当你调用fig.colorbar()并指定ax=ax3[0]/ax3[1]时,matplotlib会直接从对应的子图轴域里挤占空间来放置水平colorbar,导致第三行的子图本身被压缩,自然就比前两行的图像小了。

要解决这个问题,我们需要让colorbar占用独立的布局空间,而不是挤压原图像的区域。下面提供两种可靠的实现方案:

方法一:用GridSpec精准规划全局布局

GridSpec可以把画布拆分成更精细的网格,我们可以给第三行的colorbar单独分配一行空间,这样第三行的子图就能和前两行保持相同的高度。

修改后的代码如下:

import matplotlib.pyplot as plt
import matplotlib.image as image
import matplotlib.colors
from matplotlib.gridspec import GridSpec

# 读取图像
bird = image.imread('Desktop/bird.jpeg')

# 创建GridSpec:总共4行(前3行放子图,第4行放第三行的colorbar),2列
fig = plt.figure(figsize=(5, 6))  # 微调高度,给colorbar预留空间
gs = GridSpec(4, 2, figure=fig, 
              height_ratios=[1, 1, 1, 0.1])  # 第4行高度占比小,专门放colorbar

# 第一行子图
ax1_0 = fig.add_subplot(gs[0, 0])
ax1_0.imshow(bird)
ax1_0.set_ylabel('Row 1', size=8)
ax1_0.set_yticks([])
ax1_0.set_xticks([])

ax1_1 = fig.add_subplot(gs[0, 1])
ax1_1.imshow(bird)
ax1_1.set_yticks([])
ax1_1.set_xticks([])

# 第二行子图
ax2_0 = fig.add_subplot(gs[1, 0])
ax2_0.imshow(bird)
ax2_0.set_ylabel('Row 2', size=8)
ax2_0.set_yticks([])
ax2_0.set_xticks([])

ax2_1 = fig.add_subplot(gs[1, 1])
ax2_1.imshow(bird)
ax2_1.set_yticks([])
ax2_1.set_xticks([])

# 第三行子图(占用第3行网格)
ax3_0 = fig.add_subplot(gs[2, 0])
cmap = matplotlib.colors.LinearSegmentedColormap.from_list("", ["Red","Green","Blue"])
bird_4 = ax3_0.imshow(bird, cmap=cmap)
ax3_0.set_ylabel('Row 3', size=8)
ax3_0.set_yticks([])
ax3_0.set_xticks([])
bird_4.set_clim(vmin=-1, vmax=1)

ax3_1 = fig.add_subplot(gs[2, 1])
bird_3 = ax3_1.imshow(bird, cmap=cmap)
ax3_1.set_yticks([])
ax3_1.set_xticks([])
bird_3.set_clim(vmin=-1, vmax=1)

# 为第三行的两个子图分别创建colorbar,放在第4行对应的列
cbar0 = fig.colorbar(bird_4, orientation='horizontal', cax=fig.add_subplot(gs[3, 0]))
cbar0.set_label('CBar', size=8, rotation=0)
cbar0.ax.tick_params(labelsize=8)

cbar1 = fig.colorbar(bird_3, orientation='horizontal', cax=fig.add_subplot(gs[3, 1]))
cbar1.set_label('CBar', size=8, rotation=0)
cbar1.ax.tick_params(labelsize=8)

plt.tight_layout()
plt.show()

方法二:用make_axes_locatable为子图附加独立colorbar轴

这个方法会自动为每个子图创建一个相邻的轴域来放置colorbar,从根源上避免原图像被挤压。

修改后的代码如下:

import matplotlib.pyplot as plt
import matplotlib.image as image
import matplotlib.colors
from mpl_toolkits.axes_grid1 import make_axes_locatable

# 读取图像
bird = image.imread('Desktop/bird.jpeg')

fig, (ax1, ax2, ax3) = plt.subplots(3,2,figsize=(5,6))

# 第一行子图
ax1[0].imshow(bird)
ax1[0].set_ylabel('Row 1', size=8)
ax1[0].set_yticks([])
ax1[0].set_xticks([])
ax1[1].imshow(bird)
ax1[1].set_yticks([])
ax1[1].set_xticks([])

# 第二行子图
ax2[0].imshow(bird)
ax2[0].set_ylabel('Row 2', size=8)
ax2[0].set_yticks([])
ax2[0].set_xticks([])
ax2[1].imshow(bird)
ax2[1].set_yticks([])
ax2[1].set_xticks([])

# 生成色图
cmap = matplotlib.colors.LinearSegmentedColormap.from_list("", ["Red","Green","Blue"])

# 第三行左图:用make_axes_locatable创建colorbar轴
bird_4 = ax3[0].imshow(bird, cmap=cmap)
ax3[0].set_ylabel('Row 3', size=8)
ax3[0].set_yticks([])
ax3[0].set_xticks([])
bird_4.set_clim(vmin=-1, vmax=1)

# 分割ax3[0]的轴域,在下方添加一个用于colorbar的轴
divider = make_axes_locatable(ax3[0])
cax0 = divider.append_axes("bottom", size="10%", pad=0.3)  # size是colorbar高度,pad是间距
cbar0 = fig.colorbar(bird_4, orientation='horizontal', cax=cax0)
cbar0.set_label('CBar', size=8, rotation=0)
cbar0.ax.tick_params(labelsize=8)

# 第三行右图:同样的处理
bird_3 = ax3[1].imshow(bird, cmap=cmap)
ax3[1].set_yticks([])
ax3[1].set_xticks([])
bird_3.set_clim(vmin=-1, vmax=1)

divider = make_axes_locatable(ax3[1])
cax1 = divider.append_axes("bottom", size="10%", pad=0.3)
cbar1 = fig.colorbar(bird_3, orientation='horizontal', cax=cax1)
cbar1.set_label('CBar', size=8, rotation=0)
cbar1.ax.tick_params(labelsize=8)

plt.tight_layout()
plt.show()

这两种方法都能保证第三行的子图尺寸和前两行完全一致,同时让colorbar有独立的展示空间。你可以根据需求选择:GridSpec适合全局布局的精细调控,make_axes_locatable则更适合快速给单个子图追加colorbar的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 13:47:39