On Mon, Nov 30, 2009 at 9:04 PM, Jason Heeris <jason.hee...@gmail.com> wrote:
> Is it at all possible to have figimage draw the image OVER the top of
> the plot area? Currently I can only get it to draw underneath — even
> if I set the frame alpha to zero, it is obscured by the grid. This can
> be seen from the test code below:

I added support for zorder at the level of figure artists to svn HEAD.
 It is not a complete solution, but should be better than what we had
before, and should handle your use case.  The reason it is not
complete is that it treats the Axes at the Figure level as a *single*
artist, so draws every artist contained in the Axes at the same
relative figure order (relative orders among Axes artists are still
respected).  But you can now specify the zorder of all artists
contained by the figure, as shown in the attached example which puts
the figimages above the axes.

Some of this code is particularly tricky and difficult to get right
across use cases (eg composite figimages) and this is exacerbated by
the fact that this part of the codebase is lightly used.  So testing
will be helpful.  I'm also posting an svn diff for other devs to
review.


Index: lib/matplotlib/pyplot.py
===================================================================
--- lib/matplotlib/pyplot.py    (revision 7992)
+++ lib/matplotlib/pyplot.py    (revision 7994)
@@ -401,7 +401,7 @@
     # allow callers to override the hold state by passing hold=True|False
     ret =  gcf().figimage(*args, **kwargs)
     draw_if_interactive()
-    sci(ret)
+    #sci(ret)  # JDH figimage should not set current image -- it is
not mappable, etc
     return ret

 def figlegend(handles, labels, loc, **kwargs):
Index: lib/matplotlib/figure.py
===================================================================
--- lib/matplotlib/figure.py    (revision 7992)
+++ lib/matplotlib/figure.py    (revision 7994)
@@ -343,7 +343,8 @@
                  cmap=None,
                  vmin=None,
                  vmax=None,
-                 origin=None):
+                 origin=None,
+                 **kwargs):
         """
         call signatures::

@@ -393,11 +394,14 @@

         .. plot:: mpl_examples/pylab_examples/figimage_demo.py

+
+        Additional kwargs are Artist kwargs passed on to
+        :class:`~matplotlib.image.FigureImage`
         """

         if not self._hold: self.clf()

-        im = FigureImage(self, cmap, norm, xo, yo, origin)
+        im = FigureImage(self, cmap, norm, xo, yo, origin, **kwargs)
         im.set_array(X)
         im.set_alpha(alpha)
         if norm is None:
@@ -735,11 +739,20 @@

         if self.frameon: self.patch.draw(renderer)

+        # a list of (zorder, func_to_call, list_of_args)
+        dsu = []
+
+
         # todo: respect zorder
-        for p in self.patches: p.draw(renderer)
-        for l in self.lines: l.draw(renderer)
-        for a in self.artists: a.draw(renderer)
+        for a in self.patches:
+            dsu.append( (a.get_zorder(), a.draw, [renderer]))

+        for a in self.lines:
+            dsu.append( (a.get_zorder(), a.draw, [renderer]))
+
+        for a in self.artists:
+            dsu.append( (a.get_zorder(), a.draw, [renderer]))
+
         # override the renderer default if self.suppressComposite
         # is not None
         composite = renderer.option_image_nocomposite()
@@ -747,8 +760,8 @@
             composite = self.suppressComposite

         if len(self.images)<=1 or composite or not
allequal([im.origin for im in self.images]):
-            for im in self.images:
-                im.draw(renderer)
+            for a in self.images:
+                dsu.append( (a.get_zorder(), a.draw, [renderer]))
         else:
             # make a composite image blending alpha
             # list of (_image.Image, ox, oy)
@@ -762,21 +775,33 @@

             im.is_grayscale = False
             l, b, w, h = self.bbox.bounds
-            gc = renderer.new_gc()
-            gc.set_clip_rectangle(self.bbox)
-            gc.set_clip_path(self.get_clip_path())
-            renderer.draw_image(gc, l, b, im)
-            gc.restore()

+            def draw_composite():
+                gc = renderer.new_gc()
+                gc.set_clip_rectangle(self.bbox)
+                gc.set_clip_path(self.get_clip_path())
+                renderer.draw_image(gc, l, b, im)
+                gc.restore()
+
+            if len(ims):
+                dsu.append((ims[0].get_zorder(), draw_composite, []))
+
         # render the axes
-        for a in self.axes: a.draw(renderer)
+        for a in self.axes:
+            dsu.append( (a.get_zorder(), a.draw, [renderer]))

         # render the figure text
-        for t in self.texts: t.draw(renderer)
+        for a in self.texts:
+            dsu.append( (a.get_zorder(), a.draw, [renderer]))

-        for legend in self.legends:
-            legend.draw(renderer)
+        for a in self.legends:
+            dsu.append( (a.get_zorder(), a.draw, [renderer]))

+
+        dsu.sort()
+        for zorder, func, args in dsu:
+            func(*args)
+
"""
See pcolor_demo2 for a much faster way of generating pcolor plots
"""
import numpy as np
import matplotlib
import matplotlib.cm as cm
import matplotlib.pyplot as plt


fig = plt.figure()
Z = np.arange(10000.0)
Z.shape = 100,100
Z[:,50:] = 1.

ax = fig.add_subplot(111)
ax.grid(True)

im1 = plt.figimage(Z, xo=50, yo=0, cmap=cm.jet, origin='lower', zorder=10)
im2 = plt.figimage(Z, xo=100, yo=100, alpha=.8, cmap=cm.jet, origin='lower', zorder=10)

plt.show()



------------------------------------------------------------------------------
Join us December 9, 2009 for the Red Hat Virtual Experience,
a free event focused on virtualization and cloud computing. 
Attend in-depth sessions from your desk. Your couch. Anywhere.
http://p.sf.net/sfu/redhat-sfdev2dev
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users

Reply via email to