Skip to content

Commit 289e553

Browse files
committed
Major panel axis sharing bugfixes
1 parent 7b709db commit 289e553

File tree

1 file changed

+79
-64
lines changed

1 file changed

+79
-64
lines changed

proplot/axes.py

Lines changed: 79 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -154,10 +154,12 @@ def __init__(self, *args, number=None, main=False, **kwargs):
154154
self._left_panels = []
155155
self._right_panels = []
156156
self._tightbbox = None # bounding boxes are saved
157-
self._panel_side = None
158-
self._panel_share = False # True when "filled" with cbar/legend
159157
self._panel_parent = None
158+
self._panel_side = None
159+
self._panel_share = False
160160
self._panel_filled = False # True when "filled" with cbar/legend
161+
self._sharex_override = False
162+
self._sharey_override = False
161163
self._inset_parent = None
162164
self._inset_zoom = False
163165
self._inset_zoom_data = None
@@ -396,9 +398,8 @@ def _reassign_suplabel(self, side):
396398
paxs = getattr(ax, '_' + side + '_panels')
397399
if not paxs:
398400
return ax
399-
idx = 0 if side in ('left', 'top') else -1
400-
pax = paxs[idx]
401401
kw = {}
402+
pax = paxs[-1] # outermost is always list in list
402403
obj = getattr(ax, '_' + side + '_label')
403404
for key in ('color', 'fontproperties'): # TODO: add to this?
404405
kw[key] = getattr(obj, 'get_' + key)()
@@ -427,7 +428,7 @@ def _reassign_title(self):
427428
if not taxs or not ax._above_top_panels:
428429
tax = ax
429430
else:
430-
tax = taxs[0]
431+
tax = taxs[-1]
431432
tax._title_pad = ax._title_pad
432433
for loc in ('abc', 'left', 'center', 'right'):
433434
kw = {}
@@ -440,74 +441,69 @@ def _reassign_title(self):
440441
tobj.update(kw)
441442
obj.set_text('')
442443

443-
def _sharex_setup(self, sharex, level=None):
444+
def _sharex_setup(self, sharex):
444445
"""Configure x-axis sharing for panels. Main axis sharing is done in
445446
`~XYAxes._sharex_setup`."""
446-
if level is None:
447-
level = self.figure._sharex
448-
if level not in range(4):
449-
raise ValueError(
450-
'Invalid sharing level sharex={value!r}. '
451-
'Axis sharing level can be 0 (share nothing), '
452-
'1 (hide axis labels), '
453-
'2 (share limits and hide axis labels), or '
454-
'3 (share limits and hide axis and tick labels).'
455-
)
456-
self._share_short_axis(sharex, 'left', level)
457-
self._share_short_axis(sharex, 'right', level)
458-
self._share_long_axis(sharex, 'bottom', level)
459-
self._share_long_axis(sharex, 'top', level)
447+
self._share_short_axis(sharex, 'left')
448+
self._share_short_axis(sharex, 'right')
449+
self._share_long_axis(sharex, 'bottom')
450+
self._share_long_axis(sharex, 'top')
460451

461-
def _sharey_setup(self, sharey, level=None):
452+
def _sharey_setup(self, sharey):
462453
"""Configure y-axis sharing for panels. Main axis sharing is done in
463454
`~XYAxes._sharey_setup`."""
464-
if level is None:
465-
level = self.figure._sharey
466-
if level not in range(4):
467-
raise ValueError(
468-
'Invalid sharing level sharey={value!r}. '
469-
'Axis sharing level can be 0 (share nothing), '
470-
'1 (hide axis labels), '
471-
'2 (share limits and hide axis labels), or '
472-
'3 (share limits and hide axis and tick labels).'
473-
)
474-
self._share_short_axis(sharey, 'bottom', level)
475-
self._share_short_axis(sharey, 'top', level)
476-
self._share_long_axis(sharey, 'left', level)
477-
self._share_long_axis(sharey, 'right', level)
455+
self._share_short_axis(sharey, 'bottom')
456+
self._share_short_axis(sharey, 'top')
457+
self._share_long_axis(sharey, 'left')
458+
self._share_long_axis(sharey, 'right')
478459

479460
def _share_setup(self):
480461
"""Automatically configure axis sharing based on the horizontal and
481462
vertical extent of subplots in the figure gridspec."""
482463
# Panel axes sharing, between main subplot and its panels
464+
# NOTE: While _panel_share just means "include this panel" in the
465+
# axis sharing between the main subplot and panel children,
466+
# _sharex_override and _sharey_override say "override the sharing level
467+
# for these axes, because they belong to a panel group", and may
468+
# include the main subplot itself.
483469
def shared(paxs):
484470
return [
485471
pax for pax in paxs
486472
if not pax._panel_filled and pax._panel_share
487473
]
488474

475+
# Internal axis sharing; share stacks of panels and the main
476+
# axes with each other.
477+
# NOTE: *This* block is why, even though share[xy] are figure-wide
478+
# settings, we still need the axes-specific _share[xy]_override attr
489479
if not self._panel_side: # this is a main axes
490480
# Top and bottom
491481
bottom = self
492482
paxs = shared(self._bottom_panels)
493483
if paxs:
494484
bottom = paxs[-1]
485+
bottom._sharex_override = False
495486
for iax in (self, *paxs[:-1]):
496-
# parent is *bottom-most* panel
497-
iax._sharex_setup(bottom, 3)
487+
iax._sharex_override = True
488+
iax._sharex_setup(bottom) # parent is bottom-most
498489
paxs = shared(self._top_panels)
499490
for iax in paxs:
500-
iax._sharex_setup(bottom, 3)
491+
iax._sharex_override = True
492+
iax._sharex_setup(bottom)
501493
# Left and right
494+
# NOTE: Order of panel lists is always inside-to-outside
502495
left = self
503496
paxs = shared(self._left_panels)
504497
if paxs:
505-
left = paxs[0]
506-
for iax in (*paxs[1:], self):
507-
iax._sharey_setup(left, 3) # parent is *bottom-most* panel
498+
left = paxs[-1]
499+
left._sharey_override = False
500+
for iax in (self, *paxs[:-1]):
501+
iax._sharey_override = True
502+
iax._sharey_setup(left) # parent is left-most
508503
paxs = shared(self._right_panels)
509504
for iax in paxs:
510-
iax._sharey_setup(left, 3)
505+
iax._sharey_override = True
506+
iax._sharey_setup(left)
511507

512508
# Main axes, sometimes overrides panel axes sharing
513509
# TODO: This can get very repetitive, but probably minimal impact?
@@ -520,31 +516,31 @@ def shared(paxs):
520516
for child in children:
521517
child._sharey_setup(parent)
522518

523-
def _share_short_axis(self, share, side, level):
524-
"""Share the "short" axes of panels along a main subplot with panels
525-
along an external subplot."""
526-
if share is None or self._panel_side: # not None
527-
return
519+
def _share_short_axis(self, share, side):
520+
"""Share the "short" axes of panels belonging to this subplot
521+
with panels belonging to an external subplot."""
522+
if share is None or self._panel_side:
523+
return # if this is a panel
528524
axis = 'x' if side in ('left', 'right') else 'y'
529525
caxs = getattr(self, '_' + side + '_panels')
530526
paxs = getattr(share, '_' + side + '_panels')
531527
caxs = [pax for pax in caxs if not pax._panel_filled]
532528
paxs = [pax for pax in paxs if not pax._panel_filled]
533529
for cax, pax in zip(caxs, paxs): # may be uneven
534-
getattr(cax, '_share' + axis + '_setup')(pax, level)
530+
getattr(cax, '_share' + axis + '_setup')(pax)
535531

536-
def _share_long_axis(self, share, side, level):
537-
"""Share the "long" axes of panels along a main subplot with the
538-
axis from an external subplot."""
532+
def _share_long_axis(self, share, side):
533+
"""Share the "long" axes of panels belonging to this subplot
534+
with panels belonging to an external subplot."""
539535
# NOTE: We do not check _panel_share because that only controls
540536
# sharing with main subplot, not other subplots
541537
if share is None or self._panel_side:
542-
return
538+
return # if this is a panel
543539
axis = 'x' if side in ('top', 'bottom') else 'y'
544540
paxs = getattr(self, '_' + side + '_panels')
545541
paxs = [pax for pax in paxs if not pax._panel_filled]
546542
for pax in paxs:
547-
getattr(pax, '_share' + axis + '_setup')(share, level)
543+
getattr(pax, '_share' + axis + '_setup')(share)
548544

549545
def _update_axis_labels(self, x='x', **kwargs):
550546
"""Apply axis labels to the relevant shared axis. If spanning
@@ -1963,7 +1959,10 @@ def _hide_labels(self):
19631959
axis = getattr(self, x + 'axis')
19641960
share = getattr(self, '_share' + x)
19651961
if share is not None:
1966-
level = getattr(self.figure, '_share' + x)
1962+
level = (
1963+
3 if getattr(self, '_share' + x + '_override')
1964+
else getattr(self.figure, '_share' + x)
1965+
)
19671966
if level > 0:
19681967
axis.label.set_visible(False)
19691968
if level > 2:
@@ -1984,13 +1983,21 @@ def _make_twin_axes(self, *args, **kwargs):
19841983
self._twinned_axes.join(self, ax2)
19851984
return ax2
19861985

1987-
def _sharex_setup(self, sharex, level=None):
1986+
def _sharex_setup(self, sharex):
19881987
"""Configure shared axes accounting for panels. The input is the
19891988
'parent' axes, from which this one will draw its properties."""
1990-
# Call Axes method
1991-
if level is None:
1992-
level = self.figure._sharex
1993-
super()._sharex_setup(sharex, level) # sets up panels
1989+
# Share panel across different subplots
1990+
super()._sharex_setup(sharex)
1991+
# Get sharing level
1992+
level = 3 if self._sharex_override else self.figure._sharex
1993+
if level not in range(4):
1994+
raise ValueError(
1995+
'Invalid sharing level sharex={value!r}. '
1996+
'Axis sharing level can be 0 (share nothing), '
1997+
'1 (hide axis labels), '
1998+
'2 (share limits and hide axis labels), or '
1999+
'3 (share limits and hide axis and tick labels).'
2000+
)
19942001
if sharex in (None, self) or not isinstance(sharex, XYAxes):
19952002
return
19962003
# Builtin sharing features
@@ -1999,13 +2006,21 @@ def _sharex_setup(self, sharex, level=None):
19992006
if level > 1:
20002007
self._shared_x_axes.join(self, sharex)
20012008

2002-
def _sharey_setup(self, sharey, level=None):
2009+
def _sharey_setup(self, sharey):
20032010
"""Configure shared axes accounting for panels. The input is the
20042011
'parent' axes, from which this one will draw its properties."""
2005-
# Call Axes method
2006-
if level is None:
2007-
level = self.figure._sharey
2008-
super()._sharey_setup(sharey, level)
2012+
# Share panel across different subplots
2013+
super()._sharey_setup(sharey)
2014+
# Get sharing level
2015+
level = 3 if self._sharey_override else self.figure._sharey
2016+
if level not in range(4):
2017+
raise ValueError(
2018+
'Invalid sharing level sharey={value!r}. '
2019+
'Axis sharing level can be 0 (share nothing), '
2020+
'1 (hide axis labels), '
2021+
'2 (share limits and hide axis labels), or '
2022+
'3 (share limits and hide axis and tick labels).'
2023+
)
20092024
if sharey in (None, self) or not isinstance(sharey, XYAxes):
20102025
return
20112026
# Builtin features

0 commit comments

Comments
 (0)