“FigureCanvasAgg”对象没有“invalidate”属性?Python绘图。

15

我一直在跟进《Python数据分析》这本书。在第345页,你会看到这段用于绘制不同股票回报率的代码。然而,我的绘图函数无法工作。我得到的错误信息是"FigureCanvasAgg' object has no attribute 'invalidate'"。

names = ['AAPL','MSFT', 'DELL', 'MS', 'BAC', 'C'] #goog and SF did not work
def get_px(stock, start, end):
    return web.get_data_yahoo(stock, start, end)['Adj Close']
px = pd.DataFrame({n: get_px(n, '1/1/2009', '6/1/2012') for n in names})

#fillna method pad uses last valid observation to fill
px = px.asfreq('B').fillna(method='pad')
rets = px.pct_change()
df2 = ((1 + rets).cumprod() - 1)

df2.ix[0] = 1

df2.plot()

更新:完整的回溯

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-122-df192c0432be> in <module>()
      6 df2.ix[0] = 1
      7 
----> 8 df2.plot()

//anaconda/lib/python2.7/site-packages/pandas/tools/plotting.pyc in plot_frame(frame, x, y, subplots, sharex, sharey, use_index, figsize, grid, legend, rot, ax, style, title, xlim, ylim, logx, logy, xticks, yticks, kind, sort_columns, fontsize, secondary_y, **kwds)
   1634                      logy=logy, sort_columns=sort_columns,
   1635                      secondary_y=secondary_y, **kwds)
-> 1636     plot_obj.generate()
   1637     plot_obj.draw()
   1638     if subplots:

//anaconda/lib/python2.7/site-packages/pandas/tools/plotting.pyc in generate(self)
    854         self._compute_plot_data()
    855         self._setup_subplots()
--> 856         self._make_plot()
    857         self._post_plot_logic()
    858         self._adorn_subplots()

//anaconda/lib/python2.7/site-packages/pandas/tools/plotting.pyc in _make_plot(self)
   1238         if not self.x_compat and self.use_index and self._use_dynamic_x():
   1239             data = self._maybe_convert_index(self.data)
-> 1240             self._make_ts_plot(data, **self.kwds)
   1241         else:
   1242             lines = []

//anaconda/lib/python2.7/site-packages/pandas/tools/plotting.pyc in _make_ts_plot(self, data, **kwargs)
   1319                 self._maybe_add_color(colors, kwds, style, i)
   1320 
-> 1321                 _plot(data[col], i, ax, label, style, **kwds)
   1322 
   1323         self._make_legend(lines, labels)

//anaconda/lib/python2.7/site-packages/pandas/tools/plotting.pyc in _plot(data, col_num, ax, label, style, **kwds)
   1293         def _plot(data, col_num, ax, label, style, **kwds):
   1294             newlines = tsplot(data, plotf, ax=ax, label=label,
-> 1295                                 style=style, **kwds)
   1296             ax.grid(self.grid)
   1297             lines.append(newlines[0])

//anaconda/lib/python2.7/site-packages/pandas/tseries/plotting.pyc in tsplot(series, plotf, **kwargs)
     79 
     80     # set date formatter, locators and rescale limits
---> 81     format_dateaxis(ax, ax.freq)
     82     left, right = _get_xlim(ax.get_lines())
     83     ax.set_xlim(left, right)

//anaconda/lib/python2.7/site-packages/pandas/tseries/plotting.pyc in format_dateaxis(subplot, freq)
    258     subplot.xaxis.set_major_formatter(majformatter)
    259     subplot.xaxis.set_minor_formatter(minformatter)
--> 260     pylab.draw_if_interactive()

//anaconda/lib/python2.7/site-packages/IPython/utils/decorators.pyc in wrapper(*args, **kw)
     41     def wrapper(*args,**kw):
     42         wrapper.called = False
---> 43         out = func(*args,**kw)
     44         wrapper.called = True
     45         return out

//anaconda/lib/python2.7/site-packages/matplotlib/backends/backend_macosx.pyc in draw_if_interactive()
    227         figManager =  Gcf.get_active()
    228         if figManager is not None:
--> 229             figManager.canvas.invalidate()
    230 
    231 

AttributeError: 'FigureCanvasAgg' object has no attribute 'invalidate'

1
请粘贴完整的回溯信息。 - tacaswell
你的安装出了问题,或者是pandas在构建图形时出现了一些问题。macosx后端不应该有一个Agg画布对象。matplotlib.get_backend()返回什么? - tacaswell
@tcaswell 我已经将此作为 https://github.com/matplotlib/matplotlib/issues/4156 进行报告。 - dmnd
6个回答

23

我发现这个错误是由以下几个因素组合造成的:

  • 使用 pandas 绘图功能时,使用了系列或数据框成员方法
  • 在绘制具有日期索引的图表时
  • 在 ipython 中使用了 %matplotlib inline 魔术命令
  • 在导入 matplotlib 魔术命令之前导入了 pylab 模块

所以,在 ipython 笔记本的新启动内核中,以下代码将无法运行:

# fails 
import matplotlib.pylab
%matplotlib inline

import pandas
ser = pandas.Series(range(10), pandas.date_range(end='2014-01-01', periods=10))
ser.plot()

最好的解决方法是将魔法移动到顶部:

# succeeds
%matplotlib inline # moved up
import matplotlib.pylab

import pandas
ser = pandas.Series(range(10), pandas.date_range(end='2014-01-01', periods=10))
ser.plot()

不过,如果您将该系列传递给 matplotlib 绘图方法、不使用日期索引或者不导入 matplotlib.pylab 模块,问题也会消失。


实际上,我在代码顶部使用matplotlib魔法时遇到了问题。我发现我不能在评论中粘贴代码,但是这个问题仍然存在,因为在顶部使用%matplotlib并不是必要的。 - anddam
没事了,我重新运行所有的代码块后,在我的配置中就不再出现这个问题了。实际上,我更希望能够有一个可重现的问题,这样就可以修复它了。 - anddam
4
这个问题已经报告给IPython或Matplotlib或两者都报告过了吗?(如果答案是“都没有”,我们应该修复这个问题;-)) 有人在不使用Anaconda或其他基于Conda的设置时遇到过这个问题吗? - Chris Withers
我在Anaconda之外遇到了这个问题。 - Spencer
记录一下,我遇到了同样的错误,而且同样的修复方法也适用于稍微不同的设置(尽管在幕后可能是相同的)。%pylab inlineimport seaborn也可以解决这个问题。 - exp1orer
这就是拯救我的方法!我不记得在Python 2中有这样的行为,但也许我只是没有注意到。 - Boson Bear

2

虽然这不是一个答案,但我也无法弄清楚如何在评论中插入代码块 :)

所以我来到这个问题是因为在我的 Mac 上发生了完全相同的事情

/Users/briford/myPVE/workbench/lib/python2.7/site-packages/matplotlib/backends/backend_macosx.pyc in draw_if_interactive()
    227         figManager =  Gcf.get_active()
    228         if figManager is not None:
--> 229             figManager.canvas.invalidate()
    230 
AttributeError: 'FigureCanvasAgg' object has no attribute 'invalidate'

无论如何,我知道这并不令人满意,但只需关闭我的IPython笔记本服务并重新启动即可解决问题...耸肩...

1
我似乎解决了这个问题(至少在我的情况下)。
我在用Python 2.7在Mac上运行IPython,遇到了同样的错误。
看起来这是后端的一个问题,因为当我查看" dock "时,有相当多的Python启动器实例被打开了(不确定为什么一开始会发生这种情况)。
强制关闭它们会导致Python内核重新启动,并似乎已经解决了我的问题。 内联代码仍然存在图表显示正确

是的,你明白了!在Mac上,我们应该关闭那些额外的Python解释器实例。 - Claude COULOMBE

0

我通过在Jupyter笔记本的第一个代码单元格中添加%matplotlib inline并运行它来解决了这个问题。


0

当我使用非交互式后端(例如matplotlib.use('svg'))时,出现了这个错误。

对我来说解决方法是更改后端(例如matplotlib.use('Qt5Agg')


0
其他答案对我无效。相反,我的问题是由于我使用ipython notebook --pylab启动笔记本电脑。一旦我删除了--pylab,一切都恢复正常了。
因此,请确保您只使用ipython notebook启动ipython笔记本电脑。
(实际上,在使用--pylab时会发出警告,但是直到现在我才注意到。)

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