Hello all,
I have written a small patch which extends the functionality of
Figure.legend and pyplot.figlegend to match that of Axes.legend.
This patch allows figlegend to automatically build a legend for lines
with the "label" property set when figlegend is called without a list of
strings or object handles.
Also, the "loc" argument is made optional, and defaults to the upper
right, same as Axes.legend.
I hope the attached patch is suitable for inclusion. I have also
attached a test script showing each of the call signatures.
Thanks,
Ray Speth
lib/matplotlib/figure.py | 119 +++---
lib/matplotlib/pyplot.py | 13 -
2 files changed, 102 insertions(+), 30 deletions(-)
diff --git a/lib/matplotlib/figure.py b/lib/matplotlib/figure.py
index 36fe423..8204ddd 100644
--- a/lib/matplotlib/figure.py
+++ b/lib/matplotlib/figure.py
@@ -818,33 +818,43 @@ class Figure(Artist):
def get_axes(self):
return self.axes
-def legend(self, handles, labels, *args, **kwargs):
-"""
-Place a legend in the figure. Labels are a sequence of
-strings, handles is a sequence of
-:class:`~matplotlib.lines.Line2D` or
-:class:`~matplotlib.patches.Patch` instances, and loc can be a
-string or an integer specifying the legend location
-
-USAGE::
-
- legend( (line1, line2, line3),
- ('label1', 'label2', 'label3'),
- 'upper right')
-
-The *loc* location codes are::
-
- 'best' : 0, (currently not supported for figure legends)
- 'upper right' : 1,
- 'upper left' : 2,
- 'lower left' : 3,
- 'lower right' : 4,
- 'right': 5,
- 'center left' : 6,
- 'center right' : 7,
- 'lower center' : 8,
- 'upper center' : 9,
- 'center' : 10,
+def legend(self, *args, **kwargs):
+"""
+call signatures::
+
+ legend()
+ legend(labels)
+ legend(loc)
+ legend(labels, loc)
+ legend(handles, labels)
+ legend(handles, labels, loc)
+
+Place a legend in the figure. *labels* is a sequence of
+strings. *handles* is a sequence of
+:class:`~matplotlib.lines.Line2D`,
+:class:`~matplotlib.patches.Patch`, or
+:class:`~matplotlib.collections.RegularPolyCollection`
+instances. If neither *labels* nor *handles* is specified,
+legend entries will be created for those line, patch, and
+collection instances with a *label* property.
+
+*loc* can be a string or an integer specifying the legend
+location. The *loc* location codes are::
+
+ === =
+ Location String Location Code
+ === =
+ 'upper right' 1
+ 'upper left' 2
+ 'lower left' 3
+ 'lower right' 4
+ 'right' 5
+ 'center left' 6
+ 'center right'7
+ 'lower center'8
+ 'upper center'9
+ 'center' 10
+ === =
*loc* can also be an (x,y) tuple in figure coords, which
specifies the lower left of the legend box. figure coords are
@@ -907,8 +917,61 @@ class Figure(Artist):
.. plot:: mpl_examples/pylab_examples/figlegend_demo.py
"""
+if len(args)==0:
+handles = []
+labels = []
+for ax in self.get_axes():
+axhandles, axlabels = ax.get_legend_handles_labels()
+handles.extend(axhandles)
+labels.extend(axlabels)
+
+if len(handles) == 0:
+warnings.warn("No labeled objects found. "
+ "Use label='...' kwarg on individual plots.")
+return None
+
+elif len(args)==1:
+if is_string_like(args[0]) or isinstance(args[0], int):
+# LOC
+kwargs['loc'] = args[0]
+handles = []
+labels = []
+for ax in self.get_axes():
+axhandles, axlabels = ax.get_legend_handles_labels()
+handles.extend(axhandles)
+labels.extend(axlabels)
+
+else:
+# LABELS
+labels = args[0]
+handles = []
+for ax in self.get_axes():
+handles.extend(ax._get_legend_han