在matplotlib中添加色条时出现AttributeError错误

50
以下代码无法在Python 2.5.4上运行:
from matplotlib import pylab as pl
import numpy as np

data = np.random.rand(6,6)
fig = pl.figure(1)
fig.clf()
ax = fig.add_subplot(1,1,1)
ax.imshow(data, interpolation='nearest', vmin=0.5, vmax=0.99)
pl.colorbar()

pl.show()

错误信息为

C:\temp>python z.py
Traceback (most recent call last):
  File "z.py", line 10, in <module>
    pl.colorbar()
  File "C:\Python25\lib\site-packages\matplotlib\pyplot.py", line 1369, in colorbar
    ret = gcf().colorbar(mappable, cax = cax, ax=ax, **kw)
  File "C:\Python25\lib\site-packages\matplotlib\figure.py", line 1046, in colorbar
    cb = cbar.Colorbar(cax, mappable, **kw)
  File "C:\Python25\lib\site-packages\matplotlib\colorbar.py", line 622, in __init__
    mappable.autoscale_None() # Ensure mappable.norm.vmin, vmax
AttributeError: 'NoneType' object has no attribute 'autoscale_None'

我该如何在这段代码中添加颜色条?

下面是解释器的信息:

Python 2.5.4 (r254:67916, Dec 23 2008, 15:10:54) [MSC v.1310 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>
4个回答

89

(这是一个非常古老的问题,我知道) 你看到此问题的原因是因为你混合使用了状态机(matplotlib.pyplot)和面向对象的方法添加图像到坐标轴中。

函数plt.imshow与方法ax.imshow有微小但不同的区别。 方法ax.imshow

  • 创建并返回已添加到坐标轴中的图像

函数plt.imshow

  • 创建并返回已添加到当前坐标轴的图像,并将图像设置为“当前”图像/可映射对象(然后可以自动由plt.colorbar函数捕获)。

如果你想使用ax.imshow方法并能够使用plt.colorbar(在除了极端情况外的大多数情况下都会用到),则需要将返回的图像(它是ScalarMappable类的实例)作为第一个参数传递给plt.colorbar函数:

plt.imshow(image_file)
plt.colorbar()

不使用状态机的等价表达式是:

img = ax.imshow(image_file)
plt.colorbar(img, ax=ax)

如果在pyplot中,ax是当前的坐标轴,那么kwarg ax=ax就不需要了。


2
有没有一种方法可以从轴对象本身访问图像?假设您正在编写一个函数,该函数传递了一个已经绘制了图像的轴对象,并且您希望您的函数添加一个颜色条。我想做类似于plt.colorbar(ax.image,ax=ax)的事情。 - Emma
你可以在轴上使用“images”属性来获取轴内图像的列表。或者,可以使用“gci”(从记忆中)获取轴上的“active”图像。 - pelson
fig.colorbar() 替换 plt.colorbar(),它会起到相同的作用吗? - Manuel Pena

31

注意:我正在使用Python 2.6.2。使用您的代码会引发相同的错误,以下修改解决了这个问题。

我阅读了下面的颜色条示例:http://matplotlib.sourceforge.net/examples/pylab_examples/colorbar_tick_labelling_demo.html

from matplotlib import pylab as pl
import numpy as np

data = np.random.rand(6,6)
fig = pl.figure(1)
fig.clf()
ax = fig.add_subplot(1,1,1)
img = ax.imshow(data, interpolation='nearest', vmin=0.5, vmax=0.99)
fig.colorbar(img)

pl.show()

我不确定为什么你的例子没能成功。我对matplotlib不是很熟悉。


1
我在教程中找到了另一种解决这个问题的方法。
下面的代码将对plt.imshow()方法起作用:
def colorbar(Mappable, Orientation='vertical', Extend='both'):
    Ax = Mappable.axes
    fig = Ax.figure
    divider = make_axes_locatable(Ax)
    Cax = divider.append_axes("right", size="5%", pad=0.05)
    return fig.colorbar(
        mappable=Mappable, 
        cax=Cax,
        use_gridspec=True, 
        extend=Extend,  # mostra um colorbar full resolution de z
        orientation=Orientation
    )

fig, ax = plt.subplots(ncols=2)

img1 = ax[0].imshow(data)
colorbar(img1)

img2 = ax[1].imshow(-data)
colorbar(img2)

fig.tight_layout(h_pad=1)
plt.show()

它可能与其他绘图方法兼容性不佳。例如,它无法与Geopandas的Geodataframe绘图一起使用。

3
由于你提到了一个外部来源(教程),因此包含该来源的链接会很有用。 - roob
ax.figure 是一个了不起的工具。它允许在不直接将 fig 传递给函数的情况下实现许多功能。 - akozi

0

在你的代码中添加/编辑以下行

plot = ax.imshow(data, interpolation='nearest', vmin=0.5, vmax=0.99)
pl.colorbar(plot)

不回答问题 - invictus
答案与Gary给出的相似。 如果您尝试并编辑代码,使用我所写的任何内容,它会令人满意地回答。 问问题者的代码不起作用,因为pl.colorbar()给出了错误的实例进行绘图。代码中定义的'ax'默认是一个窗口实例。pl.colorbar()必须指向绘图实例。在我的情况下,需要将“cax”类似于Gary给出的内容提供给pl.colorbar()。 - Ishan Tomar

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