Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e987305

Browse files
committed
move the set and detect loc logic to
1 parent d066cc5 commit e987305

File tree

1 file changed

+65
-60
lines changed

1 file changed

+65
-60
lines changed

lib/matplotlib/legend.py

Lines changed: 65 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -503,57 +503,8 @@ def val_or_rc(val, rc_name):
503503
)
504504
self.parent = parent
505505

506-
loc0 = loc
507-
self._loc_used_default = loc is None
508-
if loc is None:
509-
loc = mpl.rcParams["legend.loc"]
510-
if not self.isaxes and loc in [0, 'best']:
511-
loc = 'upper right'
512-
513-
type_err_message = ("loc must be string, coordinate tuple, or"
514-
f" an integer 0-10, not {loc!r}")
515-
516-
# handle outside legends:
517-
self._outside_loc = None
518-
if isinstance(loc, str):
519-
if loc.split()[0] == 'outside':
520-
# strip outside:
521-
loc = loc.split('outside ')[1]
522-
# strip "center" at the beginning
523-
self._outside_loc = loc.replace('center ', '')
524-
# strip first
525-
self._outside_loc = self._outside_loc.split()[0]
526-
locs = loc.split()
527-
if len(locs) > 1 and locs[0] in ('right', 'left'):
528-
# locs doesn't accept "left upper", etc, so swap
529-
if locs[0] != 'center':
530-
locs = locs[::-1]
531-
loc = locs[0] + ' ' + locs[1]
532-
# check that loc is in acceptable strings
533-
loc = _api.check_getitem(self.codes, loc=loc)
534-
elif np.iterable(loc):
535-
# coerce iterable into tuple
536-
loc = tuple(loc)
537-
# validate the tuple represents Real coordinates
538-
if len(loc) != 2 or not all(isinstance(e, numbers.Real) for e in loc):
539-
raise ValueError(type_err_message)
540-
elif isinstance(loc, int):
541-
# validate the integer represents a string numeric value
542-
if loc < 0 or loc > 10:
543-
raise ValueError(type_err_message)
544-
else:
545-
# all other cases are invalid values of loc
546-
raise ValueError(type_err_message)
547-
548-
if self.isaxes and self._outside_loc:
549-
raise ValueError(
550-
f"'outside' option for loc='{loc0}' keyword argument only "
551-
"works for figure legends")
552-
553-
if not self.isaxes and loc == 0:
554-
raise ValueError(
555-
"Automatic legend placement (loc='best') not implemented for "
556-
"figure legend")
506+
# Set legend location
507+
self.set_loc(loc)
557508

558509
self._mode = mode
559510
self.set_bbox_to_anchor(bbox_to_anchor, bbox_transform)
@@ -597,10 +548,7 @@ def val_or_rc(val, rc_name):
597548

598549
# init with null renderer
599550
self._init_legend_box(handles, labels, markerfirst)
600-
601-
tmp = self._loc_used_default
602-
self._set_loc(loc)
603-
self._loc_used_default = tmp # ignore changes done by _set_loc
551+
self._legend_box.set_offset(self._findoffset)
604552

605553
# figure out title font properties:
606554
if title_fontsize is not None and title_fontproperties is not None:
@@ -692,21 +640,78 @@ def set_loc(self, loc):
692640
693641
Parameters
694642
----------
695-
alignment : {'upper left', 'upper right', 'lower left', 'lower right',
643+
loc : {'upper left', 'upper right', 'lower left', 'lower right',
696644
'upper center', 'lower center', 'center left', 'center right'
697645
'center', 'right', 'best'}.
646+
If a figure is using the constrained layout manager,
647+
the string codes of the loc keyword argument can get better
648+
layout behaviour using the prefix 'outside'.
698649
"""
699-
_loc_code = self.codes.get(loc, 'best')
700-
self._set_loc(_loc_code)
650+
loc0 = loc
651+
self._loc_used_default = loc is None
652+
if loc is None:
653+
loc = mpl.rcParams["legend.loc"]
654+
if not self.isaxes and loc in [0, 'best']:
655+
loc = 'upper right'
656+
657+
type_err_message = ("loc must be string, coordinate tuple, or"
658+
f" an integer 0-10, not {loc!r}")
701659

702-
def _set_loc(self, loc):
660+
# handle outside legends:
661+
self._outside_loc = None
662+
if isinstance(loc, str):
663+
if loc.split()[0] == 'outside':
664+
# strip outside:
665+
loc = loc.split('outside ')[1]
666+
# strip "center" at the beginning
667+
self._outside_loc = loc.replace('center ', '')
668+
# strip first
669+
self._outside_loc = self._outside_loc.split()[0]
670+
locs = loc.split()
671+
if len(locs) > 1 and locs[0] in ('right', 'left'):
672+
# locs doesn't accept "left upper", etc, so swap
673+
if locs[0] != 'center':
674+
locs = locs[::-1]
675+
loc = locs[0] + ' ' + locs[1]
676+
# check that loc is in acceptable strings
677+
loc = _api.check_getitem(self.codes, loc=loc)
678+
elif np.iterable(loc):
679+
# coerce iterable into tuple
680+
loc = tuple(loc)
681+
# validate the tuple represents Real coordinates
682+
if len(loc) != 2 or not all(isinstance(e, numbers.Real) for e in loc):
683+
raise ValueError(type_err_message)
684+
elif isinstance(loc, int):
685+
# validate the integer represents a string numeric value
686+
if loc < 0 or loc > 10:
687+
raise ValueError(type_err_message)
688+
else:
689+
# all other cases are invalid values of loc
690+
raise ValueError(type_err_message)
691+
692+
if self.isaxes and self._outside_loc:
693+
raise ValueError(
694+
f"'outside' option for loc='{loc0}' keyword argument only "
695+
"works for figure legends")
696+
697+
if not self.isaxes and loc == 0:
698+
raise ValueError(
699+
"Automatic legend placement (loc='best') not implemented for "
700+
"figure legend")
701+
702+
tmp = self._loc_used_default
703+
self._set_loc(loc, set_offset=False)
704+
self._loc_used_default = tmp # ignore changes done by _set_loc
705+
706+
def _set_loc(self, loc, set_offset=True):
703707
# find_offset function will be provided to _legend_box and
704708
# _legend_box will draw itself at the location of the return
705709
# value of the find_offset.
706710
self._loc_used_default = False
707711
self._loc_real = loc
708712
self.stale = True
709-
self._legend_box.set_offset(self._findoffset)
713+
if set_offset:
714+
self._legend_box.set_offset(self._findoffset)
710715

711716
def set_ncols(self, ncols):
712717
"""Set the number of columns."""

0 commit comments

Comments
 (0)