为两个具有相等长宽比的子图添加颜色条

7 投票
3 回答
4286 浏览
提问于 2025-04-18 04:05

我正在尝试给一个包含两个子图的图表添加一个颜色条,这两个子图的比例是相等的,也就是用 set_aspect('equal') 设置的:

在这里输入图片描述

创建这个图表的代码可以在 这个IPython笔记本 中找到。

下面的代码生成的图像(在笔记本中查看)是我能得到的最好结果,但仍然不是我想要的效果。

plt.subplot(1,2,1)
plt.pcolormesh(rand1)
plt.gca().set_aspect('equal')

plt.subplot(1,2,2)
plt.pcolormesh(rand2)
plt.gca().set_aspect('equal')

plt.tight_layout()

from mpl_toolkits.axes_grid1 import make_axes_locatable
divider = make_axes_locatable(plt.gca())
cax = divider.append_axes("right", size="5%", pad=0.05)

plt.colorbar(cax=cax)

在这里输入图片描述

这个问题似乎相关:

3 个回答

1

虽然大家认可的解决方案可以用,但感觉有点不太正规。我觉得用GridSpec会更好一些,这样做在处理更大的网格时也会更有效。

import numpy
import matplotlib.pyplot as plt
import matplotlib

nb_cols = 5
data = numpy.random.random((10, 10))

fig = plt.figure()
gs = matplotlib.gridspec.GridSpec(1, nb_cols)        
axes = [fig.add_subplot(gs[0, col], aspect="equal") for col in range(nb_cols)]

for col, ax in enumerate(axes):
    im = ax.pcolormesh(data, vmin=data.min(), vmax=data.max())
    if col > 0:
        ax.yaxis.set_visible(False)

fig.colorbar(im, ax=axes, pad=0.01, shrink=0.23)

在这里输入图片描述

4

这个解决方案和上面的那个类似,但不需要创建和丢弃颜色条。

需要注意的是,这两种解决方案都有一个潜在的问题:颜色条会使用其中一个颜色网格的颜色映射和标准化。如果这两个是相同的,那就没问题。

ImageGrid有一些看起来符合你需求的东西:

from mpl_toolkits.axes_grid1 import make_axes_locatable
fig = plt.figure(1, (4., 4.))
ax = plt.subplot(1,1,1)
divider = make_axes_locatable(ax)

cm = plt.pcolormesh(rand1)
ax.set_aspect('equal')

cax = divider.append_axes("right", size="100%", pad=0.4)
plt.pcolormesh(rand2)
cax.set_aspect('equal')

sm = plt.cm.ScalarMappable(cmap=cm.cmap, norm=cm.norm)
sm._A = []

cax = divider.append_axes("right", size="10%", pad=0.1)
plt.colorbar(sm, cax=cax)
None # Prevent text output
8

我还不太确定你具体想要什么,但我猜你是想用 pcolormesh 来创建子图,并且希望在添加颜色条时它们的大小保持一致?

我现在的方法有点取巧,因为我为两个子图都添加了一个 colorbar,这样可以确保它们的大小相同。然后我再把第一个 colorbar 删除。如果这个结果是你想要的,我可以再找一种更符合Python风格的方法来实现。目前你具体想要的还是有点模糊。

import numpy
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable


data = numpy.random.random((10, 10))

fig = plt.figure()

ax1 = fig.add_subplot(1,2,1, aspect = "equal")
ax2 = fig.add_subplot(1,2,2, aspect = "equal")

im1 = ax1.pcolormesh(data)
im2 = ax2.pcolormesh(data)

divider1 = make_axes_locatable(ax1)
cax1 = divider1.append_axes("right", size="5%", pad=0.05)

divider2 = make_axes_locatable(ax2)
cax2 = divider2.append_axes("right", size="5%", pad=0.05)

#Create and remove the colorbar for the first subplot
cbar1 = fig.colorbar(im1, cax = cax1)
fig.delaxes(fig.axes[2])

#Create second colorbar
cbar2 = fig.colorbar(im2, cax = cax2)

plt.tight_layout()

plt.show()

enter image description here

撰写回答