Included below is an updated patch fixing the legend with numpoints=1. The patch has been made against SVN and works for Line2D, LineCollection, Patch, and RegularPolyCollection. The patch could be merged.
I also think the patch could be improved. Currently, handle._marker is examined to determine if the legend should contain lines or symbols, but this is done in the _get_handles function. It would be better if that could be moved into the Legend class definition, however, I do not know how to examine handle._marker in the Legend class definition.
Again, I would appreciate any comments or improvements.
Thanks,
Paul
diff -u a/lib/matplotlib/legend.py b/lib/matplotlib/legend.py
--- a/lib/matplotlib/legend.py 2008-01-09 13:11:00.000000000 -0600
+++ b/lib/matplotlib/legend.py 2008-01-09 13:08:36.000000000 -0600
@@ -175,9 +175,7 @@
# make a trial box in the middle of the axes. relocate it
# based on it's bbox
left, top = 0.5, 0.5
- if self.numpoints == 1:
- self._xdata = npy.array([left + self.handlelen*0.5])
- else:
+ if self.numpoints > 1:
self._xdata = npy.linspace(left, left + self.handlelen, self.numpoints)
textleft = left+ self.handlelen+self.handletextsep
self.texts = self._get_texts(labels, textleft, top)
@@ -236,6 +234,7 @@
def _get_handles(self, handles, texts):
HEIGHT = self._approx_text_height()
+ left = 0.5
ret = [] # the returned legend lines
@@ -243,6 +242,10 @@
x, y = label.get_position()
x -= self.handlelen + self.handletextsep
if isinstance(handle, Line2D):
+ if self.numpoints == 1 and handle._marker == 'None':
+ self._xdata = npy.linspace(left, left + self.handlelen, 2)
+ elif self.numpoints == 1:
+ self._xdata = npy.array([left + self.handlelen*0.5])
ydata = (y-HEIGHT/2)*npy.ones(self._xdata.shape, float)
legline = Line2D(self._xdata, ydata)
legline.update_from(handle)
@@ -253,7 +256,8 @@
ret.append(legline)
elif isinstance(handle, Patch):
···
-
+ if self.numpoints == 1:
+ self._xdata = npy.linspace(left, left + self.handlelen, 2)
p = Rectangle(xy=(min(self._xdata), y-3/4*HEIGHT),
width = self.handlelen, height=HEIGHT/2,
)
@@ -263,6 +267,8 @@
p.set_clip_path(None)
ret.append(p)
elif isinstance(handle, LineCollection):
+ if self.numpoints == 1:
+ self._xdata = npy.linspace(left, left + self.handlelen, 2)
ydata = (y-HEIGHT/2)*npy.ones(self._xdata.shape, float)
legline = Line2D(self._xdata, ydata)
self._set_artist_props(legline)
@@ -277,6 +283,8 @@
ret.append(legline)
elif isinstance(handle, RegularPolyCollection):
+ if self.numpoints == 1:
+ self._xdata = npy.array([left])
p = Rectangle(xy=(min(self._xdata), y-3/4*HEIGHT),
width = self.handlelen, height=HEIGHT/2,
)
Michael Droettboom wrote:
I'm sure the radio silence to your question is just due to holidays.
Thanks for looking into this. I'd be happy to incorporate your patch when it is ready.
As for your question about plots that can include patches -- patches are virtually anything plotted that aren't lines or images. This includes rectangles, polygons and ellipses, for instance. See something like ellipse_demo.py for an example. Patches are always drawn as rectangles in the legend.
Cheers,
Mike