Quantcast

Matplotlib 1.1.0 animation vs. contour plots

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Matplotlib 1.1.0 animation vs. contour plots

John Ladasky-3
In my last post I said that upgrading Numpy to 1.6.1 restored function
to Matplotlib 1.1.0.  Well, I spoke a bit too soon.  Static contour
plots appear to work fine, but they don't play nicely with the new
animation methods.

This animation example runs without errors.

http://matplotlib.sourceforge.net/examples/animation/dynamic_image2.html

But change line 23 from this:

  im = plt.imshow(f(x, y))

to this:

  im = plt.contour(f(x, y))

and you get this:

Traceback (most recent call last):
  File "dynamic_image2.py", line 27, in <module>
    repeat_delay=1000)
  File "/usr/local/lib/python2.6/dist-packages/matplotlib/animation.py",
line 358, in __init__
    TimedAnimation.__init__(self, fig, *args, **kwargs)
  File "/usr/local/lib/python2.6/dist-packages/matplotlib/animation.py",
line 306, in __init__
    Animation.__init__(self, fig, event_source=event_source, *args,
**kwargs)
  File "/usr/local/lib/python2.6/dist-packages/matplotlib/animation.py",
line 55, in __init__
    self._init_draw()
  File "/usr/local/lib/python2.6/dist-packages/matplotlib/animation.py",
line 365, in _init_draw
    artist.set_visible(False)
AttributeError: QuadContourSet instance has no attribute 'set_visible'

Is this a Matplotlib bug, or am I still tracking down some package
dependency issue?



------------------------------------------------------------------------------
RSA(R) Conference 2012
Save $700 by Nov 18
Register now
http://p.sf.net/sfu/rsa-sfdev2dev1
_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/matplotlib-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Matplotlib 1.1.0 animation vs. contour plots

Daniel Hyams
This looks like a bug in matplotlib to me; I get the same thing.

The basic issue is that QuadContourSet is derived from an artist, and
so does not have all of the artist methods; the animation framework
depends on the things that it is animating being artists.

The following monkey patch fixes it in the example script (obviously,
it does not fix the underlying problem; for QuadContourSet to be
usable in this context, it needs to obey the artist interface).
Hopefully, it will be enough to get you up and running.  Just add the
four lines between contour call and the appending of the output of
contour() into the list "ims", and also put an "import types" at the
top.


#!/usr/bin/env python
"""
An animated image
"""
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import types
fig = plt.figure()
def f(x, y):
    return np.sin(x) + np.cos(y)
x = np.linspace(0, 2 * np.pi, 120)
y = np.linspace(0, 2 * np.pi, 100).reshape(-1, 1)
# ims is a list of lists, each row is a list of artists to draw in the
# current frame; here we are just animating one artist, the image, in
# each frame
ims = []
for i in range(60):
    x += np.pi / 15.
    y += np.pi / 20.
    im = plt.contour(f(x, y))
    def setvisible(self,vis):
       for c in self.collections: c.set_visible(vis)
    im.set_visible = types.MethodType(setvisible,im,None)
    im.axes = plt.gca()
    ims.append([im])
ani = animation.ArtistAnimation(fig, ims, interval=50, blit=True,
    repeat_delay=1000)
ani.save('dynamic_images.mp4')

plt.show()

------------------------------------------------------------------------------
RSA(R) Conference 2012
Save $700 by Nov 18
Register now
http://p.sf.net/sfu/rsa-sfdev2dev1
_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/matplotlib-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Matplotlib 1.1.0 animation vs. contour plots

Benjamin Root-2


On Sunday, November 13, 2011, Daniel Hyams <[hidden email]> wrote:
> This looks like a bug in matplotlib to me; I get the same thing.
>
> The basic issue is that QuadContourSet is derived from an artist, and
> so does not have all of the artist methods; the animation framework
> depends on the things that it is animating being artists.
>
> The following monkey patch fixes it in the example script (obviously,
> it does not fix the underlying problem; for QuadContourSet to be
> usable in this context, it needs to obey the artist interface).
> Hopefully, it will be enough to get you up and running.  Just add the
> four lines between contour call and the appending of the output of
> contour() into the list "ims", and also put an "import types" at the
> top.
>
>
> #!/usr/bin/env python
> """
> An animated image
> """
> import numpy as np
> import matplotlib.pyplot as plt
> import matplotlib.animation as animation
> import types
> fig = plt.figure()
> def f(x, y):
>     return np.sin(x) + np.cos(y)
> x = np.linspace(0, 2 * np.pi, 120)
> y = np.linspace(0, 2 * np.pi, 100).reshape(-1, 1)
> # ims is a list of lists, each row is a list of artists to draw in the
> # current frame; here we are just animating one artist, the image, in
> # each frame
> ims = []
> for i in range(60):
>     x += np.pi / 15.
>     y += np.pi / 20.
>     im = plt.contour(f(x, y))
>     def setvisible(self,vis):
>        for c in self.collections: c.set_visible(vis)
>     im.set_visible = types.MethodType(setvisible,im,None)
>     im.axes = plt.gca()
>     ims.append([im])
> ani = animation.ArtistAnimation(fig, ims, interval=50, blit=True,
>     repeat_delay=1000)
> ani.save('dynamic_images.mp4')
>
> plt.show()
>

Technically speaking, it is derived from ScalarMappable, not Artist. It is counter-intuitive, though.

Ben Root
------------------------------------------------------------------------------
RSA(R) Conference 2012
Save $700 by Nov 18
Register now
http://p.sf.net/sfu/rsa-sfdev2dev1
_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/matplotlib-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Matplotlib 1.1.0 animation vs. contour plots

Daniel Hyams
Oops; my sentence should have read "is *not* derived from an artist".

On Sun, Nov 13, 2011 at 1:24 PM, Benjamin Root <[hidden email]> wrote:

>
>
> On Sunday, November 13, 2011, Daniel Hyams <[hidden email]> wrote:
>> This looks like a bug in matplotlib to me; I get the same thing.
>>
>> The basic issue is that QuadContourSet is derived from an artist, and
>> so does not have all of the artist methods; the animation framework
>> depends on the things that it is animating being artists.
>>
>> The following monkey patch fixes it in the example script (obviously,
>> it does not fix the underlying problem; for QuadContourSet to be
>> usable in this context, it needs to obey the artist interface).
>> Hopefully, it will be enough to get you up and running.  Just add the
>> four lines between contour call and the appending of the output of
>> contour() into the list "ims", and also put an "import types" at the
>> top.
>>
>>
>> #!/usr/bin/env python
>> """
>> An animated image
>> """
>> import numpy as np
>> import matplotlib.pyplot as plt
>> import matplotlib.animation as animation
>> import types
>> fig = plt.figure()
>> def f(x, y):
>>     return np.sin(x) + np.cos(y)
>> x = np.linspace(0, 2 * np.pi, 120)
>> y = np.linspace(0, 2 * np.pi, 100).reshape(-1, 1)
>> # ims is a list of lists, each row is a list of artists to draw in the
>> # current frame; here we are just animating one artist, the image, in
>> # each frame
>> ims = []
>> for i in range(60):
>>     x += np.pi / 15.
>>     y += np.pi / 20.
>>     im = plt.contour(f(x, y))
>>     def setvisible(self,vis):
>>        for c in self.collections: c.set_visible(vis)
>>     im.set_visible = types.MethodType(setvisible,im,None)
>>     im.axes = plt.gca()
>>     ims.append([im])
>> ani = animation.ArtistAnimation(fig, ims, interval=50, blit=True,
>>     repeat_delay=1000)
>> ani.save('dynamic_images.mp4')
>>
>> plt.show()
>>
>
> Technically speaking, it is derived from ScalarMappable, not Artist. It is
> counter-intuitive, though.
>
> Ben Root



--
Daniel Hyams
[hidden email]

------------------------------------------------------------------------------
RSA(R) Conference 2012
Save $700 by Nov 18
Register now
http://p.sf.net/sfu/rsa-sfdev2dev1
_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/matplotlib-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Matplotlib 1.1.0 animation vs. contour plots

John Ladasky-3

On Sun, 2011-11-13 at 13:26 -0500, Daniel Hyams wrote:
> Oops; my sentence should have read "is *not* derived from an artist".

Yes, I was wondering about that.  I was actually looking though the
artist.py and contour.py source code when your message came in.


On Sunday, November 13, 2011, Daniel Hyams <[hidden email]> wrote:
> The following monkey patch fixes it in the example script (obviously,
> it does not fix the underlying problem; for QuadContourSet to be
> usable in this context, it needs to obey the artist interface).
> Hopefully, it will be enough to get you up and running.  Just add the
> four lines between contour call and the appending of the output of
> contour() into the list "ims", and also put an "import types" at the
> top.

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.

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'


Since the error was occurring inside blit_draw, I tried altering the
animation.ArtistAnimation() call on line 27, letting blit default to
False.  This resulted in a successful on-screen rendering, as well as a
saved file on the disk.  Mission accomplished!  Though perhaps at the
sacrifice of some speed.

Is this error occurring because there is no bit-mapped representation of
a contour object?  If so, what should matplotlib do?  Make the user be
aware that blit cannot be used with contour objects, as I just learned?
Or, alternately, make sure that animations respond intelligently to the
objects passed to them?

Many thanks again to everyone who is working through this with me!


------------------------------------------------------------------------------
RSA(R) Conference 2012
Save $700 by Nov 18
Register now
http://p.sf.net/sfu/rsa-sfdev2dev1
_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/matplotlib-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Matplotlib 1.1.0 animation vs. contour plots

Daniel Hyams
>
> 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.

--
Daniel Hyams
[hidden email]

------------------------------------------------------------------------------
RSA(R) Conference 2012
Save $700 by Nov 18
Register now
http://p.sf.net/sfu/rsa-sfdev2dev1
_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/matplotlib-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Matplotlib 1.1.0 animation vs. contour plots

Benjamin Root-2


On Sunday, November 13, 2011, Daniel Hyams <[hidden email]> 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

------------------------------------------------------------------------------
RSA(R) Conference 2012
Save $700 by Nov 18
Register now
http://p.sf.net/sfu/rsa-sfdev2dev1
_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/matplotlib-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Matplotlib 1.1.0 animation vs. contour plots

Daniel Hyams
It's not "official", but just idiomatic, I suppose ;)

http://en.wikipedia.org/wiki/Monkey_patch

http://paulirish.com/2010/duck-punching-with-jquery/


>
> Is that an official term? I have done things like this before, but never had
> a word for it.
>
> Ben Root
>



--
Daniel Hyams
[hidden email]

------------------------------------------------------------------------------
RSA(R) Conference 2012
Save $700 by Nov 18
Register now
http://p.sf.net/sfu/rsa-sfdev2dev1
_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/matplotlib-users
Loading...