问题
I've been following 'python for data analysis'. On pg. 345, you get to this code to plot returns across a variety of stocks. However, the plotting function does not work for me. I get 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()
UPDATE: full traceback
---------------------------------------------------------------------------
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:
I found this error to be due to a combination of:
- using pandas plotting with a series or dataframe member method
- plotting with a date index
- using
%matplotlib inline
magic in ipython - importing the pylab module before the matplotlib magic
So the following will fail on a newly started kernel in an ipython notebook:
# fails
import matplotlib.pylab
%matplotlib inline
import pandas
ser = pandas.Series(range(10), pandas.date_range(end='2014-01-01', periods=10))
ser.plot()
The best way to solve this is to move the magic up to the top:
# 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()
However the problem also goes away if you pass the series to a matplotlib
plotting method, don't use a date index, or simply don't import the matplotlib.pylab
module.
回答2:
Not an answer but I can't figure out how to put code block in comments :)
So I got to this question because the exact same thing was happening on my 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'
Anyway I know it's not satisfying but just doing a shutdown of my ipython notebook service and doing a restart cleared it up... shrug...
回答3:
I seemed to resolve the issue (well at least in my case).
I'm running IPython on a mac using python 2.7 and was getting the same error.
It did seem to be an issue with the backend as when I looked at the "dock", quite a few instances of the Python Launcher had been opened (not sure why this happened in the first place though).
Forcing those to close caused the python kernel to restart and has seemed to have fixed my issue.
The inline code is still in place and plots are showing correctly.
回答4:
The other answers didn't work for me. Instead my problem was because I was starting the notebook with ipython notebook --pylab
. Once I dropped the --pylab
things worked again.
So make sure you start ipython notebook with only ipython notebook
.
(There's actually a warning emitted when you use --pylab
but I missed it until now.)
来源:https://stackoverflow.com/questions/23550056/figurecanvasagg-object-has-no-attribute-invalidate-python-plotting