substantial refactoring of backends

I just finished reorganizing the backend code. The most significant
change is that backends no longer derive their own figures. Figures
now derive from Artist and are totally backend independent. All the
GUI functionality formerly in FigureBackend, is now in a new class
FigureCanvasBackend, which does Rendererer installation, GUI event
handling, etc... For GUI classes, FigureCanvasBackend should derive
from a widget you can insert into a widget container.

FigureManagerBackend is initialized with a canvas. The attribute name
canvas is standardized across backends.

So the containment is manager contains canvas contains figure.

The importance of these changes is

1) Backend switching is now perfected since figure instances contain
    *no* backend specific information - of course mainloops will prevent
    switching between gtk and wx

2) This enables a backend to render to any other non interactive
    backend (eg, PS saves from GTK or WX). More importantly, it
    enables us to have a sophisticated image backend (eg agg which
    supports alpha and antialiased drawing http://www.antigrain.com/)
    or gd (which is getting better all the time) and render to the GUI
    from the image - see attachment below.

    In other words, instead of each GUI implementing their own drawing
    and dealing with fonts and rotation and window extents etc, all
    this can be relegated to a single high quality image backend and
    the GUI canvas updated from the image. Since we're already doing
    double buffered drawing, there would be no little or no additional
    performance hit.

    All at once this buys us font standardization across GUI backends,
    arbitrary text rotation across GUI backends, and pixel for pixel
    compatibility across GUI backends. I think it's an idea worth
    serious consideration, so please weigh in.

    It would probably entail some specialized C code to move images
    from the image backend to the GUI canvas for speed. I've
    implemented a proof of concept GTK backend called GTK2. It uses
    GD for drawing the image. It's slow, because I use python to
    transfer the image, but it works. And note it is only 80 lines of
    code (matplotlib.backends.backend_gtk2), which shows how easy it
    is to plug an arbitrary image renderer into an arbitrary GUI
    backend under the new framework. As before, you can also export
    PS and EPS from this backend.

    If you want to try this out, you'll need gdmodule-0.51 (and the GD
    dependencies described at
    http://matplotlib.sourceforge.net/backends.html#GD). gd lib has
    recently added clipping and antialiased line drawing. I've
    patched the 0.51 gdmodule wrapper to add support for this and will
    email the maintainer the patch when I get some time. In the mean
    time, just replace _gdmodule.c in the 0.51 distro with the file
    I'm attaching below.

This CVS update breaks WX (sorry Jeremy!). Since Jeremy is otherwise
occupied :-), I'll try and port WX tomorrow.

For those of you using matplotlib in GUI apps, the new setup requires
some minor (one liner) API changes -- see embedding_in_gtk.py for an
example and the CVS file API_CHANGES for more info

_gdmodule.c (58.7 KB)

I just finished reorganizing the backend code. The most significant
change is that backends no longer derive their own figures. Figures
now derive from Artist and are totally backend independent. All the
GUI functionality formerly in FigureBackend, is now in a new class
FigureCanvasBackend, which does Rendererer installation, GUI event
handling, etc... For GUI classes, FigureCanvasBackend should derive
from a widget you can insert into a widget container.

FigureManagerBackend is initialized with a canvas. The attribute name
canvas is standardized across backends.

So the containment is manager contains canvas contains figure.

The importance of these changes is

1) Backend switching is now perfected since figure instances contain
    *no* backend specific information - of course mainloops will prevent
    switching between gtk and wx

2) This enables a backend to render to any other non interactive
    backend (eg, PS saves from GTK or WX). More importantly, it
    enables us to have a sophisticated image backend (eg agg which
    supports alpha and antialiased drawing http://www.antigrain.com/)
    or gd (which is getting better all the time) and render to the GUI
    from the image - see attachment below.

    In other words, instead of each GUI implementing their own drawing
    and dealing with fonts and rotation and window extents etc, all
    this can be relegated to a single high quality image backend and
    the GUI canvas updated from the image. Since we're already doing
    double buffered drawing, there would be no little or no additional
    performance hit.

    All at once this buys us font standardization across GUI backends,
    arbitrary text rotation across GUI backends, and pixel for pixel
    compatibility across GUI backends. I think it's an idea worth
    serious consideration, so please weigh in.

This is something to shoot for, but worth bearing in mind that it will
probably become quite tricky to maintain across the supported platforms. As
we stood a couple of weeks ago, Matplotlib worked on Linux (all backends),
Windows (at least wx, and non-GUI backends except GD), Mac (I believe) and
probably most other platforms.

I know that GD is not very easy to make work on Windows, and I worry that if
Matplotlib starts to have large numbers of external dependencies, it will
reduce the overall attractiveness of the library.

    It would probably entail some specialized C code to move images
    from the image backend to the GUI canvas for speed. I've
    implemented a proof of concept GTK backend called GTK2. It uses
    GD for drawing the image. It's slow, because I use python to
    transfer the image, but it works. And note it is only 80 lines of
    code (matplotlib.backends.backend_gtk2), which shows how easy it
    is to plug an arbitrary image renderer into an arbitrary GUI
    backend under the new framework. As before, you can also export
    PS and EPS from this backend.

C code, in particular, can be tricky to write in an optimal way across
platforms (e.g. Mac/Sparc are big-endian, X86 is little endian, making fast
bit blitting routines potentially tricky when used in conjunction with a
multiple set of backends.

If we can find a truly cross-platform way to render to a bitmap, which is
actively developed and supported on multiple platforms, then this would be
great - my worry is that we end up discovering that GTK, wx, Tk and so on are
actually the closest thing we have to this.

    If you want to try this out, you'll need gdmodule-0.51 (and the GD
    dependencies described at
    http://matplotlib.sourceforge.net/backends.html#GD). gd lib has
    recently added clipping and antialiased line drawing. I've
    patched the 0.51 gdmodule wrapper to add support for this and will
    email the maintainer the patch when I get some time. In the mean
    time, just replace _gdmodule.c in the 0.51 distro with the file
    I'm attaching below.

I worry that all of the above sounds rather negative, and it isn't meant to
be. However, (unlike most other Matplotlib users) my main target platform in
Windows - force of working necessity :frowning: - and I don't want to get left out
of the party...

However, if we can find the right way to do this, it would be an excellent
solution.

···

On Wednesday 28 January 2004 10:06 pm, John Hunter wrote:

This CVS update breaks WX (sorry Jeremy!). Since Jeremy is otherwise
occupied :-), I'll try and port WX tomorrow.

For those of you using matplotlib in GUI apps, the new setup requires
some minor (one liner) API changes -- see embedding_in_gtk.py for an
example and the CVS file API_CHANGES for more info