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

Skip to content

Commit a761639

Browse files
committed
FIX: add legend kwarg outside
1 parent f655c14 commit a761639

File tree

4 files changed

+39
-133
lines changed

4 files changed

+39
-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: 33 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -1755,7 +1755,7 @@ def get_axes(self):
17551755
# docstring of pyplot.figlegend.
17561756

17571757
@docstring.dedent_interpd
1758-
def legend(self, *args, **kwargs):
1758+
def legend(self, *args, outside=False, axs=None, **kwargs):
17591759
"""
17601760
Place a legend on the figure.
17611761
@@ -1779,6 +1779,16 @@ def legend(self, *args, **kwargs):
17791779
17801780
Parameters
17811781
----------
1782+
1783+
outside: bool
1784+
If ``constrained_layout=True``, then try and place legend outside
1785+
axes listed in *axs*, or highest-level gridspec if axs is empty.
1786+
Note, "center" and "best" options to *loc* do not work with
1787+
``outside=True``
1788+
1789+
axs : sequence of `~.axes.Axes`
1790+
axes to gather handles from (if *handles* is empty).
1791+
17821792
handles : list of `.Artist`, optional
17831793
A list of Artists (lines, patches) to be added to the legend.
17841794
Use this together with *labels*, if you need full control on what
@@ -1807,142 +1817,37 @@ def legend(self, *args, **kwargs):
18071817
Not all kinds of artist are supported by the legend command. See
18081818
:doc:`/tutorials/intermediate/legend_guide` for details.
18091819
"""
1820+
if axs is None:
1821+
axs = self.axes
18101822

18111823
handles, labels, extra_args, kwargs = mlegend._parse_legend_args(
1812-
self.axes,
1824+
axs,
18131825
*args,
18141826
**kwargs)
1815-
# check for third arg
1816-
if len(extra_args):
1817-
# cbook.warn_deprecated(
1818-
# "2.1",
1819-
# message="Figure.legend will accept no more than two "
1820-
# "positional arguments in the future. Use "
1821-
# "'fig.legend(handles, labels, loc=location)' "
1822-
# "instead.")
1823-
# kwargs['loc'] = extra_args[0]
1824-
# extra_args = extra_args[1:]
1825-
pass
1826-
l = mlegend.Legend(self, handles, labels, *extra_args, **kwargs)
1827-
self.legends.append(l)
1827+
if outside and not self.get_constrained_layout():
1828+
cbook._warn_external('legend outside=True method needs '
1829+
'constrained_layout=True. Setting False')
1830+
outside = False
1831+
1832+
if not outside:
1833+
l = mlegend.Legend(self, handles, labels, *extra_args, **kwargs)
1834+
self.legends.append(l)
1835+
else:
1836+
loc = kwargs.pop('loc')
1837+
if axs is None:
1838+
gs = self.get_gridspecs()[0]
1839+
else:
1840+
if isinstance(axs, GridSpecBase):
1841+
gs = axs
1842+
else:
1843+
gs = axs[0].get_gridspec()
1844+
l = gs.legend_outside(loc=loc, handles=handles, labels=labels,
1845+
**kwargs)
18281846
l._remove_method = self.legends.remove
18291847
self.stale = True
18301848
return l
18311849

18321850
@cbook._delete_parameter("3.1", "withdash")
1833-
@docstring.dedent_interpd
1834-
def legend_outside(self, *, loc=None, axs=None, **kwargs):
1835-
"""
1836-
Place a legend on the figure outside a list of axes, and automatically
1837-
make room, stealing space from the axes specified by *axs* (analogous
1838-
to what colorbar does).
1839-
1840-
To make a legend from existing artists on every axes::
1841-
1842-
legend()
1843-
1844-
To specify the axes to put the legend beside::
1845-
1846-
legend(axs=[ax1, ax2])
1847-
1848-
However, note that the legend will appear beside the gridspec that
1849-
owns these axes, so the following two calls will be the same::
1850-
1851-
fig, axs = plt.subplots(2, 2)
1852-
legend(axs=[axs[0, 0], axs[1, 0]])
1853-
legend(axs=axs)
1854-
1855-
To make a legend for a list of lines and labels::
1856-
1857-
legend(
1858-
handles=(line1, line2, line3),
1859-
labels=('label1', 'label2', 'label3'),
1860-
loc='upper right')
1861-
1862-
1863-
Parameters
1864-
----------
1865-
1866-
loc: location code for legend, optional, default=1
1867-
A legend location code, but does not support ``best`` or
1868-
``center``.
1869-
1870-
axs : sequence of `.axes.Axes` or a single `.GridSpecBase`, optional
1871-
A list of axes to put the legend beside, above, or below. This is
1872-
also the list of axes that artists will be taken from if *handles*
1873-
is empty. Note that the legend will be placed adjacent to all the
1874-
axes in the gridspec that the first element in *axs* belongs to,
1875-
so mixing axes from different gridspecs may lead to confusing
1876-
results. Also, its not possible to put the legend between
1877-
two columns or rows of the same gridspec; the legend is always
1878-
outside the gridspec. This can also be passed as a gridspec
1879-
instance directly.
1880-
1881-
handles : sequence of `.Artist`, optional
1882-
A list of Artists (lines, patches) to be added to the legend.
1883-
Use this together with *labels*, if you need full control on what
1884-
is shown in the legend and the automatic mechanism described above
1885-
is not sufficient.
1886-
1887-
The length of handles and labels should be the same in this
1888-
case. If they are not, they are truncated to the smaller length.
1889-
1890-
labels : sequence of strings, optional
1891-
A list of labels to show next to the artists.
1892-
Use this together with *handles*, if you need full control on what
1893-
is shown in the legend and the automatic mechanism described above
1894-
is not sufficient.
1895-
1896-
Other Parameters
1897-
----------------
1898-
1899-
%(_legend_kw_doc)s
1900-
1901-
Returns
1902-
-------
1903-
:class:`matplotlib.legend.Legend` instance
1904-
1905-
Notes
1906-
-----
1907-
Not all kinds of artist are supported by the legend command. See
1908-
:doc:`/tutorials/intermediate/legend_guide` for details.
1909-
1910-
Currently, `~figure.legend_outside` only works if
1911-
``constrained_layout=True``.
1912-
1913-
See Also
1914-
--------
1915-
.figure.legend
1916-
.gridspec.legend
1917-
.axes.Axes.legend
1918-
1919-
"""
1920-
1921-
if not self.get_constrained_layout():
1922-
cbook._warn_external('legend_outside method needs '
1923-
'constrained_layout, using default legend')
1924-
leg = self.legend(loc=loc, **kwargs)
1925-
return leg
1926-
1927-
if loc is None:
1928-
loc = 1 # upper right
1929-
1930-
if axs is None:
1931-
gs = self.get_gridspecs()[0]
1932-
handles, labels, extra_args, kwargs = mlegend._parse_legend_args(
1933-
self.axes, **kwargs)
1934-
else:
1935-
if isinstance(axs, GridSpecBase):
1936-
gs = axs
1937-
else:
1938-
gs = axs[0].get_gridspec()
1939-
1940-
handles, labels, extra_args, kwargs = mlegend._parse_legend_args(
1941-
axs, **kwargs)
1942-
1943-
return gs.legend_outside(loc=loc, handles=handles, labels=labels,
1944-
**kwargs)
1945-
19461851
@docstring.dedent_interpd
19471852
def text(self, x, y, s, fontdict=None, withdash=False, **kwargs):
19481853
"""

lib/matplotlib/gridspec.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ def legend_outside(self, handles=None, labels=None, axs=None, **kwargs):
220220
# stack to the top...
221221
layoutbox.vstack([leg._layoutbox, child], padding=paddingh)
222222
self.figure.legends.append(leg)
223+
223224
return leg
224225

225226

lib/matplotlib/tests/test_legend.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,7 @@ def test_figure_legend_outside():
384384
for nn, todo in enumerate(todos):
385385
fig, axs = plt.subplots(constrained_layout=True, dpi=100)
386386
axs.plot(range(10), label=f'Boo1')
387-
leg = fig.legend_outside(loc=todo)
387+
leg = fig.legend(loc=todo, outside=True)
388388
renderer = fig.canvas.get_renderer()
389389
fig.canvas.draw()
390390
assert_allclose(axs.get_window_extent(renderer=renderer).extents,

0 commit comments

Comments
 (0)
0