From a142ed0ef229888519ec272dc68321cc6cffc194 Mon Sep 17 00:00:00 2001 From: Antony Lee Date: Thu, 21 Feb 2019 22:59:34 +0100 Subject: [PATCH] Allow sharing Locators and Formatters across Axises. --- lib/matplotlib/axis.py | 43 ++++++++++++++++++++++++++++++++++++---- lib/matplotlib/figure.py | 30 ++-------------------------- 2 files changed, 41 insertions(+), 32 deletions(-) diff --git a/lib/matplotlib/axis.py b/lib/matplotlib/axis.py index bfdb62df8377..b1571a948637 100644 --- a/lib/matplotlib/axis.py +++ b/lib/matplotlib/axis.py @@ -539,14 +539,20 @@ class Ticker: """ def __init__(self): + self._axis = None self._locator = None self._formatter = None self._locator_is_default = True self._formatter_is_default = True + # The machinery below allows TickHelpers to be shared over multiple Axis. + @property def locator(self): - return self._locator + locator = self._locator + if locator is not None: + locator.set_axis(self._axis) + return locator @locator.setter def locator(self, locator): @@ -557,7 +563,10 @@ def locator(self, locator): @property def formatter(self): - return self._formatter + formatter = self._formatter + if formatter is not None: + formatter.set_axis(self._axis) + return formatter @formatter.setter def formatter(self, formatter): @@ -566,6 +575,10 @@ def formatter(self, formatter): 'matplotlib.ticker.Formatter') self._formatter = formatter + @locator.setter + def locator(self, locator): + self._locator = locator + class _LazyTickList: """ @@ -653,8 +666,8 @@ def __init__(self, axes, pickradius=15): self.isDefault_label = True self.axes = axes - self.major = Ticker() - self.minor = Ticker() + self._major = Ticker() + self._minor = Ticker() self.callbacks = cbook.CallbackRegistry() self._autolabelpos = True @@ -680,6 +693,28 @@ def __init__(self, axes, pickradius=15): self.clear() self._set_scale('linear') + # The machinery below allows TickHelpers to be shared over multiple Axis. + + @property + def major(self): + major = self._major + major._axis = self + return major + + @major.setter + def major(self, major): + self._major = major + + @property + def minor(self): + minor = self._minor + minor._axis = self + return minor + + @minor.setter + def minor(self, minor): + self._minor = minor + @property def isDefault_majloc(self): return self.major._locator_is_default diff --git a/lib/matplotlib/figure.py b/lib/matplotlib/figure.py index aae1ef07a4ae..d2921532399f 100644 --- a/lib/matplotlib/figure.py +++ b/lib/matplotlib/figure.py @@ -902,38 +902,12 @@ def delaxes(self, ax): """ Remove the `~.axes.Axes` *ax* from the figure; update the current Axes. """ - - def _reset_locators_and_formatters(axis): - # Set the formatters and locators to be associated with axis - # (where previously they may have been associated with another - # Axis instance) - axis.get_major_formatter().set_axis(axis) - axis.get_major_locator().set_axis(axis) - axis.get_minor_formatter().set_axis(axis) - axis.get_minor_locator().set_axis(axis) - - def _break_share_link(ax, grouper): - siblings = grouper.get_siblings(ax) - if len(siblings) > 1: - grouper.remove(ax) - for last_ax in siblings: - if ax is not last_ax: - return last_ax - return None - self._axstack.remove(ax) self._axobservers.process("_axes_change_event", self) self.stale = True self._localaxes.remove(ax) - - # Break link between any shared axes - for name in ax._axis_names: - last_ax = _break_share_link(ax, ax._shared_axes[name]) - if last_ax is not None: - _reset_locators_and_formatters(getattr(last_ax, f"{name}axis")) - - # Break link between any twinned axes - _break_share_link(ax, ax._twinned_axes) + for axis_name in ax._shared_axes: + ax._shared_axes[axis_name].remove(ax) # Note: in the docstring below, the newlines in the examples after the # calls to legend() allow replacing it with figlegend() to generate the