Blitting for animations

Hello,

Recently I tried to get animations to work for the Mac OS X backend with the new timer framework by implementing a TimerMac class that inherits from backend_bases.TimerBase. This seems to work fine; the code is uploaded to SVN if you'd like to try it.

I am not sure what to do about blitting though. I can imagine two uses for blitting: Either to make sure that the next figure appears instantaneously as a whole after it has been drawn off-screen, or to precalculate a background figure that is used repeatedly, and upon which the changing parts of the figure are drawn.

The latter would make sense for the Mac OS X backend also, but the former would not. Effectively, because of double buffering in Quartz all figures are automatically blitted already.

So my question is: What is the purpose of blitting for animations in matplotlib?

Best,
--Michiel.

Hello,

Recently I tried to get animations to work for the Mac OS X backend with the new timer framework by implementing a TimerMac class that inherits from backend_bases.TimerBase. This seems to work fine; the code is uploaded to SVN if you'd like to try it.

I am not sure what to do about blitting though. I can imagine two uses for blitting: Either to make sure that the next figure appears instantaneously as a whole after it has been drawn off-screen, or to precalculate a background figure that is used repeatedly, and upon which the changing parts of the figure are drawn.

The latter would make sense for the Mac OS X backend also, but the former would not. Effectively, because of double buffering in Quartz all figures are automatically blitted already.

So my question is: What is the purpose of blitting for animations in matplotlib?

As far as I know, it is only the second--speeding up the animation by not having to recalculate and redraw so much.

Eric

···

On 10/15/2010 04:37 PM, Michiel de Hoon wrote:

Best,
--Michiel.

OK, thanks. Then it makes sense to implement blitting for the Mac OS X backend as well.

Unfortunately I have hit one snag:
Drawing in Mac OS X / Quartz should be done from inside the event loop. You cannot take a graphics context and just start drawing to it; the graphics context won't be properly initialized.
In lib/matplotlib/animation.py, the actual drawing occurs here:

def _post_draw(self, framedata, blit):
    # After the frame is rendered, this handles the actual flushing of
    # the draw, which can be a direct draw_idle() or make use of the
    # blitting.
    if blit and self._drawn_artists:
        self._blit_draw(self._drawn_artists, self._blit_cache)
    else:
        self._fig.canvas.draw_idle()

Without blitting, this function calls draw_idle on the canvas, which triggers a call to figure.draw(renderer) from inside the event loop, which does the actual drawing, and all is well.

With blitting, it appears that self._blit_draw starts to draw directly to the graphics context; this won't work on Mac OS X.

Can this code be reorganized such that the blitting occurs from inside figure.draw(renderer)? In my opinion, there is no essential difference between blitting and other drawing functions, so to me it would make sense to have blitting and drawing together in figure.draw(renderer).

Best,
--Michiel.

Just to add information here. In an animation, you have to draw each frame. The actual process of displaying that draw (between the graphics card and the monitor) is very fast, however, the process of calculating the draw by the graphics card slow (relative to the display part).

So, imagine your mouse cursor moving across your screen, technically that is an animation of sorts. If everything else on the screen is static, the graphics card can keep the draw information for the static background in memory and then only bother to recalculate the draw for the mouse cursor and put that data into the appropriate place in the data of the static background.

Note, it is important to use the ‘animated=True’ kwarg for the collections and plots that will be non-static in order to take advantage of blitting. Any plot object that is tagged as animated will have their rendering deferred until explicitly told to draw.

Note that blitting isn’t always a time-saver. If most of your image is animated and there is very little static background information, the overhead of blitting will impact your rendering performance. However, for most purposes of matplotlib, blitting will improve animation performance.

I hope this is informative,
Ben Root

···

On Fri, Oct 15, 2010 at 11:46 PM, Eric Firing <efiring@…229…> wrote:

On 10/15/2010 04:37 PM, Michiel de Hoon wrote:

Hello,

Recently I tried to get animations to work for the Mac OS X backend with the new timer framework by implementing a TimerMac class that inherits from backend_bases.TimerBase. This seems to work fine; the code is uploaded to SVN if you’d like to try it.

I am not sure what to do about blitting though. I can imagine two uses for blitting: Either to make sure that the next figure appears instantaneously as a whole after it has been drawn off-screen, or to precalculate a background figure that is used repeatedly, and upon which the changing parts of the figure are drawn.

The latter would make sense for the Mac OS X backend also, but the former would not. Effectively, because of double buffering in Quartz all figures are automatically blitted already.

So my question is: What is the purpose of blitting for animations in matplotlib?

As far as I know, it is only the second–speeding up the animation by

not having to recalculate and redraw so much.

Eric

Just to note here: a lot of time in matplotlib is spent rendering
axes, ticks, and tick labels. So even if the plot elements can't be
cached, animation performance can be *vastly* improved just by
eliminating the drawing of those things.

Ryan

···

On Sat, Oct 16, 2010 at 12:54 PM, Benjamin Root <ben.root@...553...> wrote:

Note that blitting isn't always a time-saver. If most of your image is
animated and there is very little static background information, the
overhead of blitting will impact your rendering performance. However, for
most purposes of matplotlib, blitting will improve animation performance.

--
Ryan May
Graduate Research Assistant
School of Meteorology
University of Oklahoma