|
From: Benjamin R. <ben...@ou...> - 2011-11-13 22:43:04
|
On Sunday, November 13, 2011, Daniel Hyams <dh...@gm...> wrote: >> >> OK, types is a new part of the Python library for me, I'll have to go >> learn about it. It looks like you basically just subclassed the >> QuadContourSet object through a back door, by giving it the missing >> method. > > It's not a subclass, it's just a "monkey patch". I personally like > "duck punching", because even just reading the term makes me laugh: > "If it walks like a duck and quacks like a duck, it's a duck; or if it > does not walk or talk like a duck, punch it until it does". In this > case, we're punching the QuadContourSet until it behaves like an > Artist. It's a useful technique for experimenting, and can be used as > a patching technique in the interim until it is fixed properly. You > never want to write code like this on a regular basis, however. > > >> Your patch solves one of two animation problems, and I offer a >> suggestion about how to fix the second (with questions). >> >> The program gets as far as ani.save() on line 29 without generating any >> errors. An MP4 file showing animated contours is written to disk. The >> origin of the contour plot is in the lower left, versus the upper left >> of the original imshow() call, but that's expected. >> >> When you get to plt.show() on line 31, however: >> >> Traceback (most recent call last): >> File >> "/usr/local/lib/python2.6/dist-packages/matplotlib/backends/backend_gtk.py", line 127, in _on_timer >> TimerBase._on_timer(self) >> File >> "/usr/local/lib/python2.6/dist-packages/matplotlib/backend_bases.py", >> line 1091, in _on_timer >> ret = func(*args, **kwargs) >> File "/usr/local/lib/python2.6/dist-packages/matplotlib/animation.py", >> line 317, in _step >> still_going = Animation._step(self, *args) >> File "/usr/local/lib/python2.6/dist-packages/matplotlib/animation.py", >> line 179, in _step >> self._draw_next_frame(framedata, self._blit) >> File "/usr/local/lib/python2.6/dist-packages/matplotlib/animation.py", >> line 199, in _draw_next_frame >> self._post_draw(framedata, blit) >> File "/usr/local/lib/python2.6/dist-packages/matplotlib/animation.py", >> line 222, in _post_draw >> self._blit_draw(self._drawn_artists, self._blit_cache) >> File "/usr/local/lib/python2.6/dist-packages/matplotlib/animation.py", >> line 236, in _blit_draw >> bg_cache[a.axes] = a.figure.canvas.copy_from_bbox(a.axes.bbox) >> AttributeError: QuadContourSet instance has no attribute 'figure' > > It looks like just one more duck punch is needed; just set > > im.figure = fig > > after the setting of im.axes. QuadContourSet should really call > a.get_axes() and a.get_figure() instead of using the attributes > directly; doing so would allow any object that implements the proper > interfaces to work, artist or no. > >> Is this error occurring because there is no bit-mapped representation of >> a contour object? > > It's not really that, it's just that the animation class expects to be > given a list of Artists to work with (the original author can correct > me if I'm wrong), and that's not what it is being given, because a > QuadContourSet is not an Artist. But you can duck punch it until it > acts like one :D > > IMO, there are quite a few things in matplotlib that are a little > inconsistent in this way. > "duck-punching" Is that an official term? I have done things like this before, but never had a word for it. Ben Root |