关于python:如何从matplotlib中的图中检索colorbar实例

How to retrieve colorbar instance from figure in matplotlib

所有。我想在图像数据更改时更新图形的颜色条。比如:

1
2
3
4
5
6
7
8
9
10
11
img = misc.lena()
fig = plt.figure()
ax = plt.imshow(im)
plt.colorbar(ax)
newimg = img+10*np.randn(512,512)

def update_colorbar(fig,ax,newimg):
    cbar = fig.axes[1]
    ax.set_data(newimg)
    cbar.update_normal(ax)
    plt.draw()

但是,从fig.axes()返回的结果似乎不像我预期的那样具有colorbar实例。我可以将colorbar实例作为参数传递给update函数,但我认为只传递一个fig参数就足够了。有人能稍微解释一下如何从图中检索颜色条吗?或者为什么"fig.axes()"不返回axesImage或colobar实例,而只返回axes或axesSubplot?我想我需要更多的理解轴/图形的东西。谢谢!


有时,即使颜色条不是保存在变量中,也可以使用它来检索颜色条。在这种情况下,可以使用以下命令从绘图中检索颜色条:

1
2
3
4
5
6
7
8
#create a test image
img=np.arange(20).reshape(5,4)
plt.imshow(img)
plt.colorbar()

ax=plt.gca()        #plt.gca() for current axis, otherwise set appropriately.
im=ax.images        #this is a list of all images that have been plotted
cb=im[-1].colorbar   #in this case I assume to be interested to the last one plotted, otherwise use the appropriate index

现在,您可以对cb进行操作,就像存储它一样,更改xlim或调用update,如其他注释中所述。或者你可以用cb.remove()删除它,然后用plt.colorbar()重新创建它。

更新绘图后应调用plt.draw()show

顺便说一下,图像是与颜色条相关联的可映射的,可以用cb.mappable获得。


首先,我认为您在轴(基本上是绘图)、图形、标量映射(在本例中是图像)和颜色条实例之间有点困惑。

figure是地块所在的窗口。它是顶级容器。

每个数字通常有一个或多个axes。这些是图/子图。

彩条也在图中。添加颜色条将为要显示的颜色条创建新的轴(除非另有指定)。(它通常不能显示在与图像相同的轴上,因为颜色栏需要有自己的X和Y限制等。)

您的一些困惑是因为您混合了状态机接口和OO接口。可以这样做,但您需要了解OO接口。

fig.axes[1]不是colorbar实例。颜色条是在这些轴上绘制的。(同样,fig.axes[1]只是图中的第二个轴。它恰好是颜色条所在的轴,用于具有一个子批次和一个颜色条的图形,但通常情况下不会如此。)

如果要更新颜色栏,则需要保留colorbar返回的颜色栏实例。

下面是一个你通常如何处理事情的例子:

1
2
3
4
5
6
7
8
import matplotlib.pyplot as plt
import numpy as np

data = np.random.random((10,10)) # Generate some random data to plot

fig, ax = plt.subplots() # Create a figure with a single axes.
im = ax.imshow(data)     # Display the image data
cbar = fig.colorbar(im)  # Add a colorbar to the figure based on the image

如果要使用update_normal来更新颜色栏,则需要传入ScalarMappable(例如,imshow创建的图像、scatter创建的集合、contour创建的ContourSet等)。(还有其他方法可以做到这一点。通常,您只想更新限制,而不是更新整个限制。)对于上面的代码,您可以调用cbar.update_normal(im)

但是,您还没有创建新的AxesImage,您只是更改了它的数据。因此,您可能只想:

1
cbar.set_clim(newimg.min(), newimg.max())