From 4776e50f245efd987e171adff1a47e7e86563670 Mon Sep 17 00:00:00 2001 From: Tim Hoffmann <2836374+timhoffm@users.noreply.github.com> Date: Thu, 14 Dec 2017 01:20:57 +0100 Subject: [PATCH] improve legend docstring --- lib/matplotlib/axes/_axes.py | 69 ++++++++++++++++++++++++----- lib/matplotlib/figure.py | 18 ++++++++ lib/matplotlib/legend.py | 21 ++++++--- lib/matplotlib/pyplot.py | 4 +- lib/matplotlib/tests/test_legend.py | 7 ++- 5 files changed, 97 insertions(+), 22 deletions(-) diff --git a/lib/matplotlib/axes/_axes.py b/lib/matplotlib/axes/_axes.py index 27efb72b62e0..be1a4b216172 100644 --- a/lib/matplotlib/axes/_axes.py +++ b/lib/matplotlib/axes/_axes.py @@ -283,38 +283,83 @@ def legend(self, *args, **kwargs): """ Places a legend on the axes. - To make a legend for lines which already exist on the axes - (via plot for instance), simply call this function with an iterable - of strings, one for each legend item. For example:: + Call signatures:: - ax.plot([1, 2, 3]) - ax.legend(['A simple line']) + legend() + legend(labels) + legend(handles, labels) + + The call signatures correspond to three different ways how to use + this method. - However, in order to keep the "label" and the legend element - instance together, it is preferable to specify the label either at - artist creation, or by calling the - :meth:`~matplotlib.artist.Artist.set_label` method on the artist:: + **1. Automatic detection of elements to be shown in the legend** + + The elements to be added to the legend are automatically determined, + when you do not pass in any extra arguments. + + In this case, the labels are taken from the artist. You can specify + them either at artist creation or by calling the + :meth:`~.Artist.set_label` method on the artist:: line, = ax.plot([1, 2, 3], label='Inline label') - # Overwrite the label by calling the method. + ax.legend() + + or:: + line.set_label('Label via method') + line, = ax.plot([1, 2, 3]) ax.legend() Specific lines can be excluded from the automatic legend element selection by defining a label starting with an underscore. - This is default for all artists, so calling :meth:`legend` without + This is default for all artists, so calling `Axes.legend` without any arguments and without setting the labels manually will result in no legend being drawn. + + **2. Labeling existing plot elements** + + To make a legend for lines which already exist on the axes + (via plot for instance), simply call this function with an iterable + of strings, one for each legend item. For example:: + + ax.plot([1, 2, 3]) + ax.legend(['A simple line']) + + Note: This way of using is discouraged, because the relation between + plot elements and labels is only implicit by their order and can + easily be mixed up. + + + **3. Explicitly defining the elements in the legend** + For full control of which artists have a legend entry, it is possible to pass an iterable of legend artists followed by an iterable of legend labels respectively:: - legend((line1, line2, line3), ('label1', 'label2', 'label3')) + legend((line1, line2, line3), ('label1', 'label2', 'label3')) Parameters ---------- + handles : sequence of `~.Artist`, optional + A list of Artists (lines, patches) to be added to the legend. + Use this together with *labels*, if you need full control on what + is shown in the legend and the automatic mechanism described above + is not sufficient. + + The length of handles and labels should be the same in this + case. If they are not, they are truncated to the smaller length. + + labels : sequence of strings, optional + A list of labels to show next to the artists. + Use this together with *handles*, if you need full control on what + is shown in the legend and the automatic mechanism described above + is not sufficient. + + Other Parameters + ---------------- + loc : int or string or pair of floats, default: 'upper right' The location of the legend. Possible codes are: diff --git a/lib/matplotlib/figure.py b/lib/matplotlib/figure.py index e3d86e3f8438..a5141db68e4f 100644 --- a/lib/matplotlib/figure.py +++ b/lib/matplotlib/figure.py @@ -1373,6 +1373,24 @@ def legend(self, *args, **kwargs): Parameters ---------- + handles : sequence of `~.Artist`, optional + A list of Artists (lines, patches) to be added to the legend. + Use this together with *labels*, if you need full control on what + is shown in the legend and the automatic mechanism described above + is not sufficient. + + The length of handles and labels should be the same in this + case. If they are not, they are truncated to the smaller length. + + labels : sequence of strings, optional + A list of labels to show next to the artists. + Use this together with *handles*, if you need full control on what + is shown in the legend and the automatic mechanism described above + is not sufficient. + + Other Parameters + ---------------- + loc : int or string or pair of floats, default: 'upper right' The location of the legend. Possible codes are: diff --git a/lib/matplotlib/legend.py b/lib/matplotlib/legend.py index 8c2aaa9b0c16..62466ebca2e4 100644 --- a/lib/matplotlib/legend.py +++ b/lib/matplotlib/legend.py @@ -286,9 +286,7 @@ def _update_bbox_to_anchor(self, loc_in_canvas): class Legend(Artist): """ - Place a legend on the axes at location loc. Labels are a - sequence of strings and loc can be a string or an integer - specifying the legend location + Place a legend on the axes at location loc. """ codes = {'best': 0, # only implemented for axes legends @@ -353,13 +351,22 @@ def __init__(self, parent, handles, labels, handler_map=None, ): """ - - *parent*: the artist that contains the legend - - *handles*: a list of artists (lines, patches) to be added to the - legend - - *labels*: a list of strings to label the legend Parameters ---------- + parent : `.Axes` or `.Figure` + The artist that contains the legend. + + handles : sequence of `.Artist` + A list of Artists (lines, patches) to be added to the legend. + + labels : sequence of strings + A list of labels to show next to the artists. The length of handles + and labels should be the same. If they are not, they are truncated + to the smaller of both lengths. + + Other Parameters + ---------------- loc : int or string or pair of floats, default: 'upper right' The location of the legend. Possible codes are: diff --git a/lib/matplotlib/pyplot.py b/lib/matplotlib/pyplot.py index 54609f668803..2fa3417f2241 100644 --- a/lib/matplotlib/pyplot.py +++ b/lib/matplotlib/pyplot.py @@ -283,8 +283,8 @@ def pause(interval): This can be used for crude animation. For more complex animation, see :mod:`matplotlib.animation`. - Note - ---- + Notes + ----- This function is experimental; its behavior may be changed or extended in a future release. """ diff --git a/lib/matplotlib/tests/test_legend.py b/lib/matplotlib/tests/test_legend.py index da9b072aeef0..5e8c1f139872 100644 --- a/lib/matplotlib/tests/test_legend.py +++ b/lib/matplotlib/tests/test_legend.py @@ -40,9 +40,14 @@ def get_docstring_section(func, section): def test_legend_kwdocstrings(): - stleg = get_docstring_section(mpl.legend.Legend.__init__, 'Parameters') stax = get_docstring_section(mpl.axes.Axes.legend, 'Parameters') stfig = get_docstring_section(mpl.figure.Figure.legend, 'Parameters') + assert stfig == stax + + stleg = get_docstring_section(mpl.legend.Legend.__init__, + 'Other Parameters') + stax = get_docstring_section(mpl.axes.Axes.legend, 'Other Parameters') + stfig = get_docstring_section(mpl.figure.Figure.legend, 'Other Parameters') assert stleg == stax assert stfig == stax assert stleg == stfig