使用相同的色条在子图中显示Imshow

56

我希望制作4个imshow子图,它们都共享相同的颜色映射。Matplotlib自动调整颜色映射的比例取决于矩阵的条目。例如,如果我的某个矩阵所有条目都为10,另一个矩阵所有条目都为5,并且我使用Greys颜色映射,则我的其中一个子图应该完全是黑色的,而另一个则应该完全是灰色的。但两个子图最终都变成了完全黑色。如何使所有子图共享颜色映射上的相同比例?


似乎此帖子有一个可以帮助你的答案。https://dev59.com/enA75IYBdhLWcg3wS3BA - bserra
可能是[Matplotlib 2个子图,1个颜色条]的重复问题(https://dev59.com/VmYr5IYBdhLWcg3wTYgQ)。 - Ruggero Turra
3个回答

82
为了做到正确,您需要确保所有图像具有相同的强度比例,否则 colorbar() 的颜色就毫无意义了。为此,请使用 imshow()vminvmax 参数,并确保它们对于所有图像都是相同的。
例如,如果要显示的值的范围从0到10,可以使用以下代码:
import pylab as plt
import numpy as np
my_image1 = np.linspace(0, 10, 10000).reshape(100,100)
my_image2 = np.sqrt(my_image1.T) + 3
plt.subplot(1, 2, 1)
plt.imshow(my_image1, vmin=0, vmax=10, cmap='jet', aspect='auto')
plt.subplot(1, 2, 2)
plt.imshow(my_image2, vmin=0, vmax=10, cmap='jet', aspect='auto')
plt.colorbar()

输入图像描述


8
由于第二个轴较窄,所以图形不是很美观,请参考 https://dev59.com/VmYr5IYBdhLWcg3wTYgQ。 - Ruggero Turra
@RuggeroTurra 是的,但这是因为 aspect='auto',而且在任何情况下都可以通过更改子图空间(或例如网格规范)进行调整。在您链接的被接受的答案中,色条也不像轴那样高,因此仍然需要进行一些调整。 - tiago

18

当数据范围(数据1和数据2)未知,并且希望为所有绘图使用相同的色彩条时,请查找整体最小值和最大值,用作在调用imshow时的vminvmax

import numpy as np
import matplotlib.pyplot as plt

fig, axes = plt.subplots(nrows=1, ncols=2)

# generate randomly populated arrays
data1 = np.random.rand(10,10)*10 
data2 = np.random.rand(10,10)*10 -7.5

# find minimum of minima & maximum of maxima
minmin = np.min([np.min(data1), np.min(data2)])
maxmax = np.max([np.max(data1), np.max(data2)])

im1 = axes[0].imshow(data1, vmin=minmin, vmax=maxmax,
                     extent=(-5,5,-5,5), aspect='auto', cmap='viridis')
im2 = axes[1].imshow(data2, vmin=minmin, vmax=maxmax,
                     extent=(-5,5,-5,5), aspect='auto', cmap='viridis')

# add space for colour bar
fig.subplots_adjust(right=0.85)
cbar_ax = fig.add_axes([0.88, 0.15, 0.04, 0.7])
fig.colorbar(im2, cax=cbar_ax)

双imshow图像与单色条


6

也许你事先不知道数据的范围,但你可能知道它们在某种程度上是兼容的。在这种情况下,您可能更喜欢让matplotlib为第一个图选择这些范围,并对其余图使用相同的范围。以下是如何实现的。关键是使用properties()['clim']获取限制。

import numpy as np
import matplotlib.pyplot as plt

my_image1 = np.linspace(0, 10, 10000).reshape(100,100)
my_image2 = np.sqrt(my_image1.T) + 3

fig, axes = plt.subplots(nrows=1, ncols=2)
im = axes[0].imshow(my_image1)
clim=im.properties()['clim']
axes[1].imshow(my_image2, clim=clim)

fig.colorbar(im, ax=axes.ravel().tolist(), shrink=0.5)

plt.show()

1
如果第一个图的值范围比第二个图小,那么这种方法是行不通的。 - naught101
同意。但这就是我在文本中解释的内容。如果您不知道最佳范围,但假设第一个图的自动范围适用于其余图形,则此方法将起作用。 - Ramon Crehuet
@naught101,虽然晚了约3年,但以下是我解决该问题的方法:查找整体最小值和最大值,将其用作imshow中的“vmin”和“vmax”。 - airdas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接