Skip to content

Commit 59e7d13

Browse files
committed
Review actions.
1 parent 99f325d commit 59e7d13

File tree

5 files changed

+58
-10
lines changed

5 files changed

+58
-10
lines changed

doc/api/api_changes.rst

+2-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,8 @@ original location:
7575
`matplotlib.patches.Polygon` object.
7676

7777
* The legend handler interface has changed from a callable, to any object
78-
which implements the ``legend_artists`` method. See
78+
which implements the ``legend_artists`` method (a deprecation phase will
79+
see this interface be maintained for v1.4). See
7980
:ref:`plotting-guide-legend` for further details. Further legend changes
8081
include:
8182

doc/users/legend_guide.rst

+11-7
Original file line numberDiff line numberDiff line change
@@ -42,23 +42,27 @@ handles and their associated labels. This functionality is equivalent to::
4242

4343
The :meth:`~matplotlib.axes.Axes.get_legend_handles_labels` function returns
4444
a list of handles/artists which exist on the Axes which can be used to
45-
generate entries for the resulting legend.
45+
generate entries for the resulting legend - it is worth noting however that
46+
not all artists can be added to a legend, at which point a "proxy" will have
47+
to be created (see :ref:`proxy_legend_handles` for further details).
4648

4749
For full control of what is being added to the legend, it is common to pass
4850
the appropriate handles directly to :func:`legend`::
4951

50-
line2, = plt.plot([1,2,3], label='Line 2')
51-
line1, = plt.plot([3,2,1], label='Line 1')
52-
plt.legend(handles=[line1, line2])
52+
line_up, = plt.plot([1,2,3], label='Line 2')
53+
line_down, = plt.plot([3,2,1], label='Line 1')
54+
plt.legend(handles=[line_up, line_down])
5355

5456
In some cases, it is not possible to set the label of the handle, so it is
5557
possible to pass through the list of labels to :func:`legend`::
5658

57-
line2, = plt.plot([1,2,3], label='Line 2')
58-
line1, = plt.plot([3,2,1], label='Line 1')
59-
plt.legend([line1, line2], ['Custom label for line 1', 'Line 1'])
59+
line_up, = plt.plot([1,2,3], label='Line 2')
60+
line_down, = plt.plot([3,2,1], label='Line 1')
61+
plt.legend([line_up, line_down], ['Line Up', 'Line Down'])
6062

6163

64+
.. _proxy_legend_handles:
65+
6266
Creating artists specifically for adding to the legend (aka. Proxy artists)
6367
===========================================================================
6468

lib/matplotlib/backends/__init__.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
# ipython relies on interactive_bk being defined here
1111
from matplotlib.rcsetup import interactive_bk
1212

13-
__all__ = ['backend']
13+
__all__ = ['backend','show','draw_if_interactive',
14+
'new_figure_manager', 'backend_version']
1415

1516
backend = matplotlib.get_backend() # validates, to match all_backends
1617

lib/matplotlib/legend.py

+14-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@
3333

3434
from matplotlib import rcParams
3535
from matplotlib.artist import Artist, allow_rasterization
36-
from matplotlib.cbook import is_string_like, iterable, silent_list, safezip
36+
from matplotlib.cbook import (is_string_like, iterable, silent_list, safezip,
37+
warn_deprecated)
3738
from matplotlib.font_manager import FontProperties
3839
from matplotlib.lines import Line2D
3940
from matplotlib.patches import Patch, Rectangle, Shadow, FancyBboxPatch
@@ -621,6 +622,18 @@ def _init_legend_box(self, handles, labels):
621622
height=height,
622623
xdescent=0., ydescent=descent)
623624
handleboxes.append(handlebox)
625+
626+
# Deprecate the old behaviour of accepting callable
627+
# legend handlers in favour of the "legend_artist"
628+
# interface.
629+
if (not hasattr(handler, 'legend_artist') and
630+
callable(handler)):
631+
handler.legend_artist = handler.__call__
632+
warn_deprecated('1.4',
633+
('Legend handers must now implement a '
634+
'"legend_artist" method rather than '
635+
'being a callable.'))
636+
624637
# Create the artist for the legend which represents the
625638
# original artist/handle.
626639
handle_list.append(handler.legend_artist(self, orig_handle,

lib/matplotlib/tests/test_legend.py

+29
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@
99
import numpy as np
1010

1111
from matplotlib.testing.decorators import image_comparison, cleanup
12+
from matplotlib.cbook import MatplotlibDeprecationWarning
1213
import matplotlib.pyplot as plt
1314
import matplotlib as mpl
15+
import matplotlib.patches as mpatches
1416

1517

1618
@image_comparison(baseline_images=['legend_auto1'], remove_text=True)
@@ -130,6 +132,33 @@ def test_legend_label_loc_args(self):
130132
deprecation.assert_called_with('1.4', self.deprecation_message)
131133
Legend.assert_called_with(plt.gca(), [], ['hello world'], loc=1)
132134

135+
@cleanup
136+
def test_old_legend_handler_interface(self):
137+
# Check the deprecated warning is created and that the appropriate
138+
# call to the legend handler is made.
139+
class AnyObject(object):
140+
pass
141+
142+
class AnyObjectHandler(object):
143+
def __call__(self, legend, orig_handle, fontsize, handlebox):
144+
x0, y0 = handlebox.xdescent, handlebox.ydescent
145+
width, height = handlebox.width, handlebox.height
146+
patch = mpatches.Rectangle([x0, y0], width, height, facecolor='red',
147+
edgecolor='black', hatch='xx', lw=3,
148+
transform=handlebox.get_transform())
149+
handlebox.add_artist(patch)
150+
return patch
151+
152+
with mock.patch('warnings.warn') as warn:
153+
plt.legend([None], ['My first handler'],
154+
handler_map={None: AnyObjectHandler()})
155+
156+
warn.assert_called_with(u'Legend handers must now implement a '
157+
'"legend_artist" method rather than '
158+
'being a callable.',
159+
MatplotlibDeprecationWarning,
160+
stacklevel=1)
161+
133162
@cleanup
134163
def test_legend_handle_label_loc_args(self):
135164
# Check the deprecated warning is created and that the appropriate

0 commit comments

Comments
 (0)