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_handles())
+ handles = handles[:len(labels)]
+
+ elif len(args)==2:
+ if is_string_like(args[1]) or isinstance(args[1], int):
+ # LABELS, LOC
+ labels, loc = args
+ handles = []
+ for ax in self.get_axes():
+ handles.extend(ax._get_legend_handles())
+ handles = handles[:len(labels)]
+ kwargs['loc'] = loc
+ else:
+ # LINES, LABELS
+ handles, labels = args
+
+ elif len(args)==3:
+ # LINES, LABELS, LOC
+ handles, labels, loc = args
+ kwargs['loc'] = loc
+
+ else:
+ raise TypeError('Invalid arguments to legend')
+
handles = flatten(handles)
- l = Legend(self, handles, labels, *args, **kwargs)
+ l = Legend(self, handles, labels, **kwargs)
self.legends.append(l)
return l
diff --git a/lib/matplotlib/pyplot.py b/lib/matplotlib/pyplot.py
index e53df1a..9134514 100644
--- a/lib/matplotlib/pyplot.py
+++ b/lib/matplotlib/pyplot.py
@@ -404,8 +404,17 @@ def figimage(*args, **kwargs):
#sci(ret) # JDH figimage should not set current image -- it is not mappable, etc
return ret
-def figlegend(handles, labels, loc, **kwargs):
+def figlegend(*args, **kwargs):
"""
+ call signatures::
+
+ figlegend()
+ figlegend(labels)
+ figlegend(loc)
+ figlegend(labels, loc)
+ figlegend(handles, labels)
+ figlegend(handles, labels, loc)
+
Place a legend in the figure.
*labels*
@@ -432,7 +441,7 @@ def figlegend(handles, labels, loc, **kwargs):
:func:`~matplotlib.pyplot.legend`
"""
- l = gcf().legend(handles, labels, loc, **kwargs)
+ l = gcf().legend(*args, **kwargs)
draw_if_interactive()
return l
--
1.6.0.4
#!/usr/bin/python
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(10)
def makefig():
f = plt.figure()
s1 = plt.subplot(2,1,1)
s2 = plt.subplot(2,1,2)
h1 = s1.plot(x, x**2, 'ro-',label='square')
h2 = s2.plot(x, x**0.5, 'g--', label='sqrt')
return h1,h2
# none (loc->upper right)
makefig()
plt.figlegend()
# loc
makefig()
plt.figlegend('center')
# labels
makefig()
plt.figlegend(['thing1','thing2'])
# labels, loc
makefig()
plt.figlegend(['foo','bar'],'center left')
# lines, labels
h1,h2 = makefig()
plt.figlegend([h1,h2],['foo','bar'])
# lines, labels, loc
h1,h2 = makefig()
plt.figlegend([h2,h1],['bar','foo'],'upper left')
plt.show()
------------------------------------------------------------------------------
Download Intel® Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
_______________________________________________
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel