Recently I realized that there is a potential problem in both the Cairo and the 
Mac OS X backend related to how graphics contexts are handled. I tried your 
example and found that the Mac OS X backend shows the same incorrect result as 
the Cairo backend, which makes me suspect that this bug is related to the 
graphics context problem.

The problem is that matplotlib backends have a new_gc method, which is supposed 
to return a new graphics context. Unfortunately, Cairo and Quartz (used in the 
Mac OS X backend) do not have the capability to create a graphics context on 
the fly. Instead, Cairo and Quartz can save and restore graphics states on a 
stack. Both backends use a mock new_gc method by saving the graphics context on 
the stack, and trying to find that graphics context back in the stack when 
needed. This works most of the time, but it is fragile.

To give you another example where this breaks, 

text(0, 0, 'my text', bbox=dict(facecolor='grey'),color='red')

shows the text in red with the tkagg backend, but in black with the Cairo and 
Mac OS X backends. The error occurs in the draw method in text.py:

        gc = renderer.new_gc()
        gc.set_foreground(self._color)
        gc.set_alpha(self._alpha)
        gc.set_url(self._url)
        if self.get_clip_on():
            gc.set_clip_rectangle(self.clipbox)

        if self._bbox:
            bbox_artist(self, renderer, self._bbox)

Inside bbox_artist, new_gc() is called again, which is OK on backends with a 
"true" new_gc, but will lose the information stored in the existing graphics 
context in backends with a mock new_gc.

My guess is that in the bug you're seeing, the clipping path in one graphics 
context is overwritten by the clipping path in another graphics context. Maybe 
I'm wrong, but I hope that this gives you some idea of where to look.

If this is indeed the problem, maybe it's a good idea for matplotlib to save 
and restore graphics contexts instead of using new_gc? It's easy to implement a 
save/restore mechanism in backends with a new_gc capability; the reverse is 
inherently fragile.

--Michiel


--- On Thu, 3/19/09, Nathaniel Smith <n...@pobox.com> wrote:

> From: Nathaniel Smith <n...@pobox.com>
> Subject: [matplotlib-devel] Rendering (clipping?) bug with Cairo backend
> To: matplotlib-devel@lists.sourceforge.net
> Date: Thursday, March 19, 2009, 7:13 AM
> I ran into a very curious bug tonight, where if I
>   -- had multiple axes in a figure
>   -- and they had axison=False
>   -- and there was a patch or line in each axes
>   -- and there was an image in each axes
> Then the image is not rendered (or, after some fiddling
> with how the
> subplots overlap, is sometimes partially rendered).
> 
> It took a few hours to isolate :-(.
> 
> I tried the GTKCairo and GTKAgg backends; the Cairo backend
> shows the
> bug, while the Agg backend renders it correctly.
> 
> This is with matplotlib 0.98.5.2, running on Linux x86-64.
> 
> Minimal code to reproduce the bug is:
> --------
> from matplotlib import patches, pyplot
> def bug():
>     f = pyplot.figure()
>     a1 = f.add_axes([0, 0, 0.4, 0.9])
>     a2 = f.add_axes([0.5, 0, 0.4, 0.9])
>     a3 = f.add_axes([0.2, 0.2, 0.4, 0.9])
>     for a in [a1, a2, a3]:
>         # This shows up in axis 1, but not axis 2, and only
> partially in axis 3:
>         a.imshow(np.arange(100).reshape(10, 10),
>                  extent=(-1, 1, 1, -1))
>         # If you comment out either of these lines, then it
> works properly:
>         a.axison = False
>         a.plot([0, 0], [1, 1])
>     pyplot.draw()
> -------
> 
> Renders with agg and cairo are attached for comparison.
> Note that in
> the cairo rendering, axes 1 is drawn correctly, axes 2 is
> not drawn at
> all, and the only part of axes 3 that is drawn is that part
> that
> overlaps axes 2.
> 
> -- Nathaniel
> ------------------------------------------------------------------------------
> Apps built with the Adobe(R) Flex(R) framework and Flex
> Builder(TM) are
> powering Web 2.0 with engaging, cross-platform
> capabilities. Quickly and
> easily build your RIAs with Flex Builder, the
> Eclipse(TM)based development
> software that enables intelligent coding and step-through
> debugging.
> Download the free 60 day trial.
> http://p.sf.net/sfu/www-adobe-com_______________________________________________
> Matplotlib-devel mailing list
> Matplotlib-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/matplotlib-devel


      

------------------------------------------------------------------------------
Apps built with the Adobe(R) Flex(R) framework and Flex Builder(TM) are
powering Web 2.0 with engaging, cross-platform capabilities. Quickly and
easily build your RIAs with Flex Builder, the Eclipse(TM)based development
software that enables intelligent coding and step-through debugging.
Download the free 60 day trial. http://p.sf.net/sfu/www-adobe-com
_______________________________________________
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel

Reply via email to