30

全部。我想在更改图像数据时更新图形的颜色条。所以像:

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() 返回的结果没有我预期的颜色条实例。我可能只是将颜色条实例作为参数传递给更新函数,但我认为只传递一个 fig 参数可能就足够了。谁能解释一下如何从图中检索颜色条?或者为什么 'fig.axes()' 不返回 AxesImage 或 Colobar 实例,而只返回 Axes 或 AxesSubplot?我想我只需要更多地了解 Axes/Figure 的东西。谢谢!

4

2 回答 2

52

有时,即使颜色条没有保存在变量中,检索颜色条也会很有用。

在这种情况下,可以使用以下命令从图中检索颜色条:

# Create an example image and colourbar
img = np.arange(20).reshape(5,4)
plt.imshow(img)
plt.colorbar()

# Get the current axis 
ax = plt.gca()        

# Get the images on an axis
im = ax.images        

# Assume colorbar was plotted last one plotted last
cb = im[-1].colorbar   

# Do any actions on the colorbar object (e.g. remove it)
cb.remove()

编辑:

或者,等效地,一个班轮:

plt.gca().images[-1].colorbar.remove()

注意:另请参见使用 ofax.collections[-1]而不是 的 注释ax.images[-1]。对我来说,它总是只工作第一种方式,我不知道取决于什么,也许是数据或情节的类型。


现在您可以像使用colorbar APIcb中描述的命令存储它一样进行操作。例如,您可以更改或调用更新,如其他评论中所述。您可以使用 删除它并使用 重新创建它。xlimcb.remove()plt.colorbar()

plt.draw()或者show应该在更新情节之后调用。

由于图像是与颜色条关联的可映射对象,并且可以使用cb.mappable.

于 2015-12-03T06:23:14.010 回答
29

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

figure是绘图所在的窗口。它是顶级容器。

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

颜色条也在图中。添加颜色条会为要显示的颜色条创建一个新轴(除非您另外指定)。(它通常不能与图像显示在相同的轴上,因为颜色条需要有自己的 x 和 y 限制, ETC。)

您的一些困惑是由于您混合了状态机接口和 OO 接口这一事实。这样做很好,但是你需要了解OO接口。

fig.axes[1]不是颜色条实例。它是绘制颜色条的轴。(另外,fig.axes[1]只是图中的第二个轴。它恰好是颜色条所在的轴,用于具有一个子图和一个颜色条的图形,但通常不会是案子。)

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

这是您通常如何处理事情的示例:

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的集合等)。(还有其他方法可以做到这一点。通常你只想更新限制,而不是整个事情。)在上面的代码的情况下,你会调用. ContourSetcontourcbar.update_normal(im)

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

cbar.set_clim(newimg.min(), newimg.max())
于 2013-11-06T16:36:13.800 回答