Skip to content

Commit 91ac49b

Browse files
committed
Use same panel for non-overlapping outer leg/cbar
1 parent 9246835 commit 91ac49b

File tree

1 file changed

+37
-15
lines changed

1 file changed

+37
-15
lines changed

proplot/axes/base.py

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -769,7 +769,7 @@ def __init__(self, *args, **kwargs):
769769
self._inset_zoom = False
770770
self._inset_zoom_artists = None
771771
self._panel_hidden = False # True when "filled" with cbar/legend
772-
self._panel_align = set() # store align values for "filled" cbar/legend
772+
self._panel_align = {} # store 'align' and 'length' for "filled" cbar/legend
773773
self._panel_parent = None
774774
self._panel_share = False
775775
self._panel_sharex_group = False
@@ -852,17 +852,37 @@ def _add_guide_frame(
852852
self.add_artist(patch)
853853
return patch
854854

855-
def _add_guide_panel(self, loc='fill', align='center', **kwargs):
855+
def _add_guide_panel(self, loc='fill', align='center', length=0, **kwargs):
856856
"""
857857
Add a panel to be filled by an "outer" colorbar or legend.
858858
"""
859+
# Helper function: Return bounds inferred from given align setting.
860+
def _align_bbox(align, length):
861+
if align in ('left', 'bottom'):
862+
bounds = [[0, 0], [length, 0]]
863+
elif align in ('top', 'right'):
864+
bounds = [[1 - length, 0], [1, 0]]
865+
else:
866+
bounds = [[0.5 * (1 - length), 0], [0.5 * (1 + length), 0]]
867+
return mtransforms.Bbox(bounds)
868+
# NOTE: For colorbars we include 'length' when determining whether to allocate
869+
# new panel but for legend just test whether that 'align' position was filled.
859870
# WARNING: Hide content but 1) do not use ax.set_visible(False) so that
860871
# tight layout will include legend and colorbar and 2) do not use
861872
# ax.clear() so that top panel title and a-b-c label can remain.
862-
if loc in ('left', 'right', 'top', 'bottom'):
863-
ax = self.panel_axes(loc, filled=True, **kwargs)
864-
elif loc == 'fill':
873+
if loc == 'fill':
865874
ax = self
875+
elif loc in ('left', 'right', 'top', 'bottom'):
876+
ax = None
877+
bbox = _align_bbox(align, length)
878+
for pax in self._panel_dict[loc]:
879+
if not pax._panel_hidden or align in pax._panel_align:
880+
continue
881+
if not any(bbox.overlaps(_align_bbox(a, l)) for a, l in pax._panel_align.items()): # noqa: E501
882+
ax = pax
883+
break
884+
if ax is None:
885+
ax = self.panel_axes(loc, filled=True, **kwargs)
866886
else:
867887
raise ValueError(f'Invalid filled panel location {loc!r}.')
868888
for s in ax.spines.values():
@@ -871,7 +891,7 @@ def _add_guide_panel(self, loc='fill', align='center', **kwargs):
871891
ax.yaxis.set_visible(False)
872892
ax.patch.set_facecolor('none')
873893
ax._panel_hidden = True
874-
ax._panel_align.add(align)
894+
ax._panel_align[align] = length
875895
return ax
876896

877897
def _add_inset_axes(
@@ -919,6 +939,7 @@ def _add_inset_axes(
919939
def _add_colorbar(
920940
self, mappable, values=None, *,
921941
loc=None, space=None, pad=None, align=None,
942+
width=None, length=None, shrink=None,
922943
label=None, title=None, reverse=False,
923944
rotation=None, grid=None, edges=None, drawedges=None,
924945
extend=None, extendsize=None, extendfrac=None,
@@ -940,6 +961,7 @@ def _add_colorbar(
940961
# and implement inset colorbars the same as inset legends.
941962
grid = _not_none(grid=grid, edges=edges, drawedges=drawedges, default=rc['colorbar.grid']) # noqa: E501
942963
align = _translate_loc(align, 'panel', default='center', c='center', center='center') # noqa: E501
964+
length = _not_none(length=length, shrink=shrink)
943965
label = _not_none(title=title, label=label)
944966
labelloc = _not_none(labelloc=labelloc, labellocation=labellocation)
945967
locator = _not_none(ticks=ticks, locator=locator)
@@ -989,16 +1011,16 @@ def _add_colorbar(
9891011
# Generate and prepare the colorbar axes
9901012
# NOTE: The inset axes function needs 'label' to know how to pad the box
9911013
# TODO: Use seperate keywords for frame properties vs. colorbar edge properties?
992-
width = kwargs.pop('width', None)
9931014
if loc in ('fill', 'left', 'right', 'top', 'bottom'):
994-
kwargs['align'] = align
1015+
length = _not_none(length, rc['colorbar.length'])
1016+
kwargs.update({'align': align, 'length': length})
9951017
extendsize = _not_none(extendsize, rc['colorbar.extend'])
996-
ax = self._add_guide_panel(loc, width=width, space=space, pad=pad)
1018+
ax = self._add_guide_panel(loc, align, length=length, width=width, space=space, pad=pad) # noqa: E501
9971019
cax, kwargs = ax._parse_colorbar_filled(**kwargs)
9981020
else:
999-
kwargs['label'] = label # for frame calculations
1021+
kwargs.update({'label': label, 'length': length, 'width': width})
10001022
extendsize = _not_none(extendsize, rc['colorbar.insetextend'])
1001-
cax, kwargs = self._parse_colorbar_inset(loc=loc, pad=pad, width=width, **kwargs) # noqa: E501
1023+
cax, kwargs = self._parse_colorbar_inset(loc=loc, pad=pad, **kwargs) # noqa: E501
10021024

10031025
# Parse the colorbar mappable
10041026
# NOTE: Account for special case where auto colorbar is generated from 1D
@@ -1160,7 +1182,7 @@ def _add_legend(
11601182

11611183
# Generate and prepare the legend axes
11621184
if loc in ('fill', 'left', 'right', 'top', 'bottom'):
1163-
lax = self._add_guide_panel(loc, width=width, space=space, pad=pad)
1185+
lax = self._add_guide_panel(loc, align, width=width, space=space, pad=pad)
11641186
kwargs.setdefault('borderaxespad', 0)
11651187
if not frameon:
11661188
kwargs.setdefault('borderpad', 0)
@@ -1837,8 +1859,8 @@ def _parse_colorbar_arg(
18371859
return mappable, locator, formatter, kwargs
18381860

18391861
def _parse_colorbar_filled(
1840-
self, length=None, shrink=None, align=None,
1841-
tickloc=None, ticklocation=None, orientation=None, **kwargs
1862+
self, length=None, align=None, tickloc=None, ticklocation=None,
1863+
orientation=None, **kwargs
18421864
):
18431865
"""
18441866
Return the axes and adjusted keyword args for a panel-filling colorbar.
@@ -1847,7 +1869,7 @@ def _parse_colorbar_filled(
18471869
side = self._panel_side
18481870
side = _not_none(side, 'left' if orientation == 'vertical' else 'bottom')
18491871
align = _not_none(align, 'center')
1850-
length = _not_none(length=length, shrink=shrink, default=rc['colorbar.length'])
1872+
length = _not_none(length=length, default=rc['colorbar.length'])
18511873
ticklocation = _not_none(tickloc=tickloc, ticklocation=ticklocation)
18521874

18531875
# Calculate inset bounds for the colorbar

0 commit comments

Comments
 (0)