10000 FIX: add legend kwarg outside · matplotlib/matplotlib@3daa93b · GitHub
[go: up one dir, main page]

Skip to content

Commit 3daa93b

Browse files
committed
FIX: add legend kwarg outside
1 parent 5a50b8a commit 3daa93b

File tree

4 files changed

+38
-133
lines changed

4 files changed

+38
-133
lines changed

examples/text_labels_and_annotations/figlegendoutside_demo.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@
2828
axs[1].plot(x, y3, 'yd-', label='Line3')
2929
h4, = axs[1].plot(x, y4, 'k^', label='Line4')
3030

31-
fig.legend_outside(loc='upper center', ncol=2)
32-
fig.legend_outside(axs=[axs[1]], loc='lower right')
33-
fig.legend_outside(handles=[h2, h4], labels=['curve2', 'curve4'],
34-
loc='center left', borderaxespad=6)
31+
fig.legend(loc='upper center', outside=True, ncol=2)
32+
fig.legend(axs=[axs[1]], outside=True, loc='lower right')
33+
fig.legend(handles=[h2, h4], labels=['curve2', 'curve4'],
34+
outside=True, loc='center left', borderaxespad=6)
3535
plt.show()

lib/matplotlib/figure.py

Lines changed: 32 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -1701,7 +1701,7 @@ def get_axes(self):
17011701
# docstring of pyplot.figlegend.
17021702

17031703
@docstring.dedent_interpd
1704-
def legend(self, *args, **kwargs):
1704+
def legend(self, *args, outside=False, axs=None, **kwargs):
17051705
"""
17061706
Place a legend on the figure.
17071707
@@ -1726,6 +1726,15 @@ def legend(self, *args, **kwargs):
17261726
Parameters
17271727
----------
17281728
1729+
outside: bool
1730+
If ``constrained_layout=True``, then try and place legend outside
1731+
axes listed in *axs*, or highest-level gridspec if axs is empty.
1732+
Note, "center" and "best" options to *loc* do not work with
1733+
``outside=True``
1734+
1735+
axs : sequence of `~.axes.Axes`
1736+
axes to gather handles from (if *handles* is empty).
1737+
17291738
handles : sequence of `.Artist`, optional
17301739
A list of Artists (lines, patches) to be added to the legend.
17311740
Use this together with *labels*, if you need full control on what
@@ -1755,141 +1764,36 @@ def legend(self, *args, **kwargs):
17551764
Not all kinds of artist are supported by the legend command. See
17561765
:doc:`/tutorials/intermediate/legend_guide` for details.
17571766
"""
1767+
if axs is None:
1768+
axs = self.axes
17581769

17591770
handles, labels, extra_args, kwargs = mlegend._parse_legend_args(
1760-
self.axes,
1771+
axs,
17611772
*args,
17621773
**kwargs)
1763-
# check for third arg
1764-
if len(extra_args):
1765-
# cbook.warn_deprecated(
1766-
# "2.1",
1767-
# message="Figure.legend will accept no more than two "
1768-
# "positional arguments in the future. Use "
1769-
# "'fig.legend(handles, labels, loc=location)' "
1770-
# "instead.")
1771-
# kwargs['loc'] = extra_args[0]
1772-
# extra_args = extra_args[1:]
1773-
pass
1774-
l = mlegend.Legend(self, handles, labels, *extra_args, **kwargs)
1775-
self.legends.append(l)
1774+
if outside and not self.get_constrained_layout():
1775+
cbook._warn_external('legend outside=True method needs '
1776+
'constrained_layout=True. Setting False')
1777+
outside = False
1778+
1779+
if not outside:
1780+
l = mlegend.Legend(self, handles, labels, *extra_args, **kwargs)
1781+
self.legends.append(l)
1782+
else:
1783+
loc = kwargs.pop('loc')
1784+
if axs is None:
1785+
gs = self.get_gridspecs()[0]
1786+
else:
1787+
if isinstance(axs, GridSpecBase):
1788+
gs = axs
1789+
else:
1790+
gs = axs[0].get_gridspec()
1791+
l = gs.legend_outside(loc=loc, handles=handles, labels=labels,
1792+
**kwargs)
17761793
l._remove_method = self.legends.remove
17771794
self.stale = True
17781795
return l
17791796

1780-
@docstring.dedent_interpd
1781-
def legend_outside(self, *, loc=None, axs=None, **kwargs):
1782-
"""
1783-
Place a legend on the figure outside a list of axes, and automatically
1784-
make room, stealing space from the axes specified by *axs* (analogous
1785-
to what colorbar does).
1786-
1787-
To make a legend from existing artists on every axes::
1788-
1789-
legend()
1790-
1791-
To specify the axes to put the legend beside::
1792-
1793-
legend(axs=[ax1, ax2])
1794-
1795-
However, note that the legend will appear beside the gridspec that
1796-
owns these axes, so the following two calls will be the same::
1797-
1798-
fig, axs = plt.subplots(2, 2)
1799-
legend(axs=[axs[0, 0], axs[1, 0]])
1800-
legend(axs=axs)
1801-
1802-
To make a legend for a list of lines and labels::
1803-
1804-
legend(
1805-
handles=(line1, line2, line3),
1806-
labels=('label1', 'label2', 'label3'),
1807-
loc='upper right')
1808-
1809-
1810-
Parameters
1811-
----------
1812-
1813-
loc: location code for legend, optional, default=1
1814-
A legend location code, but does not support ``best`` or
1815-
``center``.
1816-
1817-
axs : sequence of `.axes.Axes` or a single `.GridSpecBase`, optional
1818-
A list of axes to put the legend beside, above, or below. This is
1819-
also the list of axes that artists will be taken from if *handles*
1820-
is empty. Note that the legend will be placed adjacent to all the
1821-
axes in the gridspec that the first element in *axs* belongs to,
1822-
so mixing axes from different gridspecs may lead to confusing
1823-
results. Also, its not possible to put the legend between
1824-
two columns or rows of the same gridspec; the legend is always
1825-
outside the gridspec. This can also be passed as a gridspec
1826-
instance directly.
1827-
1828-
handles : sequence of `.Artist`, optional
1829-
A list of Artists (lines, patches) to be added to the legend.
1830-
Use this together with *labels*, if you need full control on what
1831-
is shown in the legend and the automatic mechanism described above
1832-
is not sufficient.
1833-
1834-
The length of handles and labels should be the same in this
1835-
case. If they are not, they are truncated to the smaller length.
1836-
1837-
labels : sequence of strings, optional
1838-
A list of labels to show next to the artists.
1839-
Use this together with *handles*, if you need full control on what
1840-
is shown in the legend and the automatic mechanism described above
1841-
is not sufficient.
1842-
1843-
Other Parameters
1844-
----------------
1845-
1846-
%(_legend_kw_doc)s
1847-
1848-
Returns
1849-
-------
1850-
:class:`matplotlib.legend.Legend` instance
1851-
1852-
Notes
1853-
-----
1854-
Not all kinds of artist are supported by the legend command. See
1855-
:doc:`/tutorials/intermediate/legend_guide` for details.
1856-
1857-
Currently, `~figure.legend_outside` only works if
1858-
``constrained_layout=True``.
1859-
1860-
See Also
1861-
--------
1862-
.figure.legend
1863-
.gridspec.legend
1864-
.axes.Axes.legend
1865-
1866-
"""
1867-
1868-
if not self.get_constrained_layout():
1869-
cbook._warn_external('legend_outside method needs '
1870-
'constrained_layout, using default legend')
1871-
leg = self.legend(loc=loc, **kwargs)
1872-
return leg
1873-
1874-
if loc is None:
1875-
loc = 1 # upper right
1876-
1877-
if axs is None:
1878-
gs = self.get_gridspecs()[0]
1879-
handles, labels, extra_args, kwargs = mlegend._parse_legend_args(
1880-
self.axes, **kwargs)
1881-
else:
1882-
if isinstance(axs, GridSpecBase):
1883-
gs = axs
1884-
else:
1885-
gs = axs[0].get_gridspec()
1886-
1887-
handles, labels, extra_args, kwargs = mlegend._parse_legend_args(
1888-
axs, **kwargs)
1889-
1890-
return gs.legend_outside(loc=loc, handles=handles, labels=labels,
1891-
**kwargs)
1892-
18931797
@docstring.dedent_interpd
18941798
def text(self, x, y, s, fontdict=None, withdash=False, **kwargs):
18951799
"""

lib/matplotlib/gridspec.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ def legend_outside(self, handles=None, labels=None, axs=None, **kwargs):
216216
# stack to the top...
217217
layoutbox.vstack([leg._layoutbox, child], padding=paddingh)
218218
self.figure.legends.append(leg)
219+
219220
return leg
220221

221222

lib/matplotlib/tests/test_legend.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,7 @@ def test_figure_legend_outside():
391391
for nn, todo in enumerate(todos):
392392
fig, axs = plt.subplots(constrained_layout=True, dpi=100)
393393
axs.plot(range(10), label=f'Boo1')
394-
leg = fig.legend_outside(loc=todo)
394+
leg = fig.legend(loc=todo, outside=True)
395395
renderer = fig.canvas.get_renderer()
396396
fig.canvas.draw()
397397
assert_allclose(axs.get_window_extent(renderer=renderer).extents,

0 commit comments

Comments
 (0)
0