如何从matplotlib中的图形中检索颜色条实例

Posted

技术标签:

【中文标题】如何从matplotlib中的图形中检索颜色条实例【英文标题】:How to retrieve colorbar instance from figure in matplotlib 【发布时间】:2013-11-17 23:16: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 的东西。谢谢!

【问题讨论】:

【参考方案1】:

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

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

# 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()

注意:另请参阅 cmets 以使用 ax.collections[-1] 而不是 ax.images[-1]。对我来说,它总是只工作第一种方式,我不知道取决于什么,可能是数据或绘图的类型。


现在您可以对cb 进行操作,就好像它是使用the colorbar API 中描述的命令存储的一样。例如,您可以更改 xlim 或调用更新,如其他 cmets 中所述。您可以使用cb.remove() 删除它,然后使用plt.colorbar() 重新创建它。

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

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

【讨论】:

这个解决方案有什么问题吗(为什么要投反对票)?看来这正好回答了这个问题。 在我的情况下,ax.images 是一个空列表,即使那里有一个彩条。 很难说没有看到代码,但在我看来,只有在(任何一个)以下情况下才会发生这种情况:1)您没有检索到正确的轴; 2)您没有绘制任何图像(例如,您制作了散点图或绘制了没有图像的颜色条)。 @DanielSank 我也遇到了同样的问题,但可以改用ax.collections[-1].colorbar ax.collections[-1].colorbar 也对我有用 - 使用通过 pandas 创建的 hexbin。【参考方案2】:

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

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

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

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

您的一些困惑是由于您混合了状态机接口和 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 创建的集合、contourContourSet创建等)要传入。(还有其他方法可以做到这一点。通常你只是想更新限制,而不是整个事情。)在上面的代码的情况下,你会打电话给@ 987654333@。

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

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

【讨论】:

谢谢!这让事情变得更加清晰!所以这意味着一旦将颜色条或绘图放置到axes 上,axes 就不会在其中保存这些实例?我很好奇的另一件事是,我可以将axes 添加到axes,只是为了将一些情节组合在一起吗?再次感谢! 好吧,axes 拥有它所有的“子”艺术家(例如,在其上绘制的任何东西),但颜色条通常绘制在单独的轴上。这有帮助吗?我对你的第二个问题感到困惑......如果你想“分组”地块,只需将它们绘制在相同的轴上。您可以在彼此之上添加轴(这就是 twinx 所做的事情),但这可能不是您想要做的。 是的,它真的很有帮助! @乔。我知道保持颜色条实例更新可能是最好的做事方式,我只是想知道我是否可以通过调用颜色条绘制到的axesget_children() 来检索对象。对于第二个问题,对不起,我没有说得很清楚。我正在考虑一起处理几个图,例如将图像轴和颜色条轴作为一个组一起移动或缩小,同时保持它们的相对位置/大小等。感谢您的时间! 是的,彩条制作完成后如何找回?假设我有绘制颜色条的轴,如何获得该颜色条? @DanielSank - 颜色栏链接到创建它的艺术家,而不是特定的轴。如果您有艺术家(例如上例中的im),颜色条将为im.colorbar。当然,最好在创建颜色条时直接保存对颜色条的引用,但这并不总是可行的。无论如何,如果您使用pyplot 接口,您可以使用plt.gci().colorbar 来获取最近创建的颜色条。如果不是,则相当于fig._gci().colorbar

以上是关于如何从matplotlib中的图形中检索颜色条实例的主要内容,如果未能解决你的问题,请参考以下文章

使用颜色条删除图像不会释放 matplotlib 中的内存?

设置 Matplotlib 颜色条大小以匹配图形

感谢matplotlib,如何在同一图中显示具有重叠数据的多个图形?

Matplotlib - 如何删除颜色条但保持热图位置不变

Matplotlib:quiver 和 imshow 叠加,如何设置两个颜色条?

matplotlib 中的科学记数法颜色条