@@ -94,51 +94,7 @@ def _update_bbox_to_anchor(self, loc_in_canvas):
9494 self .legend .set_bbox_to_anchor (loc_in_bbox )
9595
9696
97- _docstring .interpd .update (_legend_kw_doc = """
98- loc : str or pair of floats, default: :rc:`legend.loc` ('best' for axes, \
99- 'upper right' for figures)
100- The location of the legend.
101-
102- The strings
103- ``'upper left', 'upper right', 'lower left', 'lower right'``
104- place the legend at the corresponding corner of the axes/figure.
105-
106- The strings
107- ``'upper center', 'lower center', 'center left', 'center right'``
108- place the legend at the center of the corresponding edge of the
109- axes/figure.
110-
111- The string ``'center'`` places the legend at the center of the axes/figure.
112-
113- The string ``'best'`` places the legend at the location, among the nine
114- locations defined so far, with the minimum overlap with other drawn
115- artists. This option can be quite slow for plots with large amounts of
116- data; your plotting speed may benefit from providing a specific location.
117-
118- The location can also be a 2-tuple giving the coordinates of the lower-left
119- corner of the legend in axes coordinates (in which case *bbox_to_anchor*
120- will be ignored).
121-
122- For back-compatibility, ``'center right'`` (but no other location) can also
123- be spelled ``'right'``, and each "string" locations can also be given as a
124- numeric value:
125-
126- =============== =============
127- Location String Location Code
128- =============== =============
129- 'best' 0
130- 'upper right' 1
131- 'upper left' 2
132- 'lower left' 3
133- 'lower right' 4
134- 'right' 5
135- 'center left' 6
136- 'center right' 7
137- 'lower center' 8
138- 'upper center' 9
139- 'center' 10
140- =============== =============
141-
97+ _legend_kw_doc_base = """
14298bbox_to_anchor : `.BboxBase`, 2-tuple, or 4-tuple of floats
14399 Box that is used to position the legend in conjunction with *loc*.
144100 Defaults to `axes.bbox` (if called as a method to `.Axes.legend`) or
@@ -295,7 +251,79 @@ def _update_bbox_to_anchor(self, loc_in_canvas):
295251
296252draggable : bool, default: False
297253 Whether the legend can be dragged with the mouse.
298- """ )
254+ """
255+
256+ _loc_doc_base = """
257+ loc : str or pair of floats, {0}
258+ The location of the legend.
259+
260+ The strings
261+ ``'upper left', 'upper right', 'lower left', 'lower right'``
262+ place the legend at the corresponding corner of the axes/figure.
263+
264+ The strings
265+ ``'upper center', 'lower center', 'center left', 'center right'``
266+ place the legend at the center of the corresponding edge of the
267+ axes/figure.
268+
269+ The string ``'center'`` places the legend at the center of the axes/figure.
270+
271+ The string ``'best'`` places the legend at the location, among the nine
272+ locations defined so far, with the minimum overlap with other drawn
273+ artists. This option can be quite slow for plots with large amounts of
274+ data; your plotting speed may benefit from providing a specific location.
275+
276+ The location can also be a 2-tuple giving the coordinates of the lower-left
277+ corner of the legend in axes coordinates (in which case *bbox_to_anchor*
278+ will be ignored).
279+
280+ For back-compatibility, ``'center right'`` (but no other location) can also
281+ be spelled ``'right'``, and each "string" locations can also be given as a
282+ numeric value:
283+
284+ =============== =============
285+ Location String Location Code
286+ =============== =============
287+ 'best' 0
288+ 'upper right' 1
289+ 'upper left' 2
290+ 'lower left' 3
291+ 'lower right' 4
292+ 'right' 5
293+ 'center left' 6
294+ 'center right' 7
295+ 'lower center' 8
296+ 'upper center' 9
297+ 'center' 10
298+ =============== =============
299+ {1}"""
300+
301+ _legend_kw_axes_st = (_loc_doc_base .format ("default: :rc:`legend.loc`" , '' ) +
302+ _legend_kw_doc_base )
303+ _docstring .interpd .update (_legend_kw_axes = _legend_kw_axes_st )
304+
305+ _outside_doc = """
306+ If a figure is using the constrained layout manager, the string codes
307+ of the *loc* keyword argument can get better layout behaviour using the
308+ prefix 'outside'. There is ambiguity at the corners, so 'outside
309+ upper right' will make space for the legend above the rest of the
310+ axes in the layout, and 'outside right upper' will make space on the
311+ right side of the layout. In addition to the values of *loc*
312+ listed above, we have 'outside right upper', 'outside right lower',
313+ 'outside left upper', and 'outside left lower'. See
314+ :doc:`/tutorials/intermediate/legend_guide` for more details.
315+ """
316+
317+ _legend_kw_figure_st = (_loc_doc_base .format ("default: 'upper right'" ,
318+ _outside_doc ) +
319+ _legend_kw_doc_base )
320+ _docstring .interpd .update (_legend_kw_figure = _legend_kw_figure_st )
321+
322+ _legend_kw_both_st = (
323+ _loc_doc_base .format ("default: 'best' for axes, 'upper right' for figures" ,
324+ _outside_doc ) +
325+ _legend_kw_doc_base )
326+ _docstring .interpd .update (_legend_kw_doc = _legend_kw_both_st )
299327
300328
301329class Legend (Artist ):
@@ -482,13 +510,37 @@ def val_or_rc(val, rc_name):
482510 )
483511 self .parent = parent
484512
513+ loc0 = loc
485514 self ._loc_used_default = loc is None
486515 if loc is None :
487516 loc = mpl .rcParams ["legend.loc" ]
488517 if not self .isaxes and loc in [0 , 'best' ]:
489518 loc = 'upper right'
519+
520+ # handle outside legends:
521+ self ._outside_loc = None
490522 if isinstance (loc , str ):
523+ if loc .split ()[0 ] == 'outside' :
524+ # strip outside:
525+ loc = loc .split ('outside ' )[1 ]
526+ # strip "center" at the beginning
527+ self ._outside_loc = loc .replace ('center ' , '' )
528+ # strip first
529+ self ._outside_loc = self ._outside_loc .split ()[0 ]
530+ locs = loc .split ()
531+ if len (locs ) > 1 and locs [0 ] in ('right' , 'left' ):
532+ # locs doesn't accept "left upper", etc, so swap
533+ if locs [0 ] != 'center' :
534+ locs = locs [::- 1 ]
535+ loc = locs [0 ] + ' ' + locs [1 ]
536+ # check that loc is in acceptable strings
491537 loc = _api .check_getitem (self .codes , loc = loc )
538+
539+ if self .isaxes and self ._outside_loc :
540+ raise ValueError (
541+ f"'outside' option for loc='{ loc0 } ' keyword argument only "
542+ "works for figure legends" )
543+
492544 if not self .isaxes and loc == 0 :
493545 raise ValueError (
494546 "Automatic legend placement (loc='best') not implemented for "
0 commit comments