diff --git a/lib/matplotlib/axes/_base.py b/lib/matplotlib/axes/_base.py index cdb3be543937..614c4f9009be 100644 --- a/lib/matplotlib/axes/_base.py +++ b/lib/matplotlib/axes/_base.py @@ -1212,6 +1212,7 @@ def cla(self): self.set_xlim(0, 1) except TypeError: pass + self.set_autoscalex_on(True) if self._sharey is not None: self.sharey(self._sharey) else: @@ -1220,6 +1221,7 @@ def cla(self): self.set_ylim(0, 1) except TypeError: pass + self.set_autoscaley_on(True) # update the minor locator for x and y axis based on rcParams if mpl.rcParams['xtick.minor.visible']: @@ -1227,10 +1229,6 @@ def cla(self): if mpl.rcParams['ytick.minor.visible']: self.yaxis.set_minor_locator(mticker.AutoMinorLocator()) - if self._sharex is None: - self._autoscaleXon = True - if self._sharey is None: - self._autoscaleYon = True self._xmargin = mpl.rcParams['axes.xmargin'] self._ymargin = mpl.rcParams['axes.ymargin'] self._tight = None @@ -2561,17 +2559,15 @@ def in_axes(self, mouseevent): """ return self.patch.contains(mouseevent)[0] + get_autoscalex_on = _axis_method_wrapper("xaxis", "_get_autoscale_on") + get_autoscaley_on = _axis_method_wrapper("yaxis", "_get_autoscale_on") + set_autoscalex_on = _axis_method_wrapper("xaxis", "_set_autoscale_on") + set_autoscaley_on = _axis_method_wrapper("yaxis", "_set_autoscale_on") + def get_autoscale_on(self): """Return True if each axis is autoscaled, False otherwise.""" - return self._autoscaleXon and self._autoscaleYon - - def get_autoscalex_on(self): - """Return whether the x-axis is autoscaled.""" - return self._autoscaleXon - - def get_autoscaley_on(self): - """Return whether the y-axis is autoscaled.""" - return self._autoscaleYon + return all(axis._get_autoscale_on() + for axis in self._get_axis_map().values()) def set_autoscale_on(self, b): """ @@ -2582,30 +2578,8 @@ def set_autoscale_on(self, b): ---------- b : bool """ - self._autoscaleXon = b - self._autoscaleYon = b - - def set_autoscalex_on(self, b): - """ - Set whether the x-axis is autoscaled on the next draw or call to - `.Axes.autoscale_view`. - - Parameters - ---------- - b : bool - """ - self._autoscaleXon = b - - def set_autoscaley_on(self, b): - """ - Set whether the y-axis is autoscaled on the next draw or call to - `.Axes.autoscale_view`. - - Parameters - ---------- - b : bool - """ - self._autoscaleYon = b + for axis in self._get_axis_map().values(): + axis._set_autoscale_on(b) @property def use_sticky_edges(self): @@ -2798,14 +2772,16 @@ def autoscale(self, enable=True, axis='both', tight=None): scalex = True scaley = True else: - scalex = False - scaley = False if axis in ['x', 'both']: - self._autoscaleXon = bool(enable) - scalex = self._autoscaleXon + self.set_autoscalex_on(bool(enable)) + scalex = self.get_autoscalex_on() + else: + scalex = False if axis in ['y', 'both']: - self._autoscaleYon = bool(enable) - scaley = self._autoscaleYon + self.set_autoscaley_on(bool(enable)) + scaley = self.get_autoscaley_on() + else: + scaley = False if tight and scalex: self._xmargin = 0 if tight and scaley: @@ -2864,13 +2840,13 @@ def autoscale_view(self, tight=None, scalex=True, scaley=True): # called very early in the Axes init process (e.g., for twin Axes) # when these attributes don't even exist yet, in which case # `get_children` would raise an AttributeError. - if self._xmargin and scalex and self._autoscaleXon: + if self._xmargin and scalex and self.get_autoscalex_on(): x_stickies = np.sort(np.concatenate([ artist.sticky_edges.x for ax in self._shared_axes["x"].get_siblings(self) if hasattr(ax, "_children") for artist in ax.get_children()])) - if self._ymargin and scaley and self._autoscaleYon: + if self._ymargin and scaley and self.get_autoscaley_on(): y_stickies = np.sort(np.concatenate([ artist.sticky_edges.y for ax in self._shared_axes["y"].get_siblings(self) @@ -2881,10 +2857,10 @@ def autoscale_view(self, tight=None, scalex=True, scaley=True): if self.get_yscale() == 'log': y_stickies = y_stickies[y_stickies > 0] - def handle_single_axis(scale, autoscaleon, shared_axes, name, - axis, margin, stickies, set_bound): + def handle_single_axis( + scale, shared_axes, name, axis, margin, stickies, set_bound): - if not (scale and autoscaleon): + if not (scale and axis._get_autoscale_on()): return # nothing to do... shared = shared_axes.get_siblings(self) @@ -2947,11 +2923,11 @@ def handle_single_axis(scale, autoscaleon, shared_axes, name, # End of definition of internal function 'handle_single_axis'. handle_single_axis( - scalex, self._autoscaleXon, self._shared_axes["x"], 'x', - self.xaxis, self._xmargin, x_stickies, self.set_xbound) + scalex, self._shared_axes["x"], 'x', self.xaxis, self._xmargin, + x_stickies, self.set_xbound) handle_single_axis( - scaley, self._autoscaleYon, self._shared_axes["y"], 'y', - self.yaxis, self._ymargin, y_stickies, self.set_ybound) + scaley, self._shared_axes["y"], 'y', self.yaxis, self._ymargin, + y_stickies, self.set_ybound) def _get_axis_list(self): return tuple(getattr(self, f"{name}axis") for name in self._axis_names) diff --git a/lib/matplotlib/axis.py b/lib/matplotlib/axis.py index bcdd56fb3119..796663013eea 100644 --- a/lib/matplotlib/axis.py +++ b/lib/matplotlib/axis.py @@ -686,6 +686,7 @@ def __init__(self, axes, pickradius=15): self.clear() self._set_scale('linear') + self._autoscale_on = True @property def isDefault_majloc(self): @@ -778,6 +779,21 @@ def _set_scale(self, value, **kwargs): def limit_range_for_scale(self, vmin, vmax): return self._scale.limit_range_for_scale(vmin, vmax, self.get_minpos()) + def _get_autoscale_on(self): + """Return whether this Axis is autoscaled.""" + return self._autoscale_on + + def _set_autoscale_on(self, b): + """ + Set whether this Axis is autoscaled when drawing or by + `.Axes.autoscale_view`. + + Parameters + ---------- + b : bool + """ + self._autoscale_on = b + def get_children(self): return [self.label, self.offsetText, *self.get_major_ticks(), *self.get_minor_ticks()] @@ -1088,7 +1104,7 @@ def _set_lim(self, v0, v1, *, emit=True, auto): for ax in self.axes._shared_axes[name].get_siblings(self.axes): ax._stale_viewlims[name] = False if auto is not None: - setattr(self.axes, f"_autoscale{name.upper()}on", bool(auto)) + self._set_autoscale_on(bool(auto)) if emit: self.axes.callbacks.process(f"{name}lim_changed", self.axes) diff --git a/lib/matplotlib/image.py b/lib/matplotlib/image.py index a7642a2cb21e..84ac88022f53 100644 --- a/lib/matplotlib/image.py +++ b/lib/matplotlib/image.py @@ -976,9 +976,9 @@ def set_extent(self, extent): self.axes.update_datalim(corners) self.sticky_edges.x[:] = [xmin, xmax] self.sticky_edges.y[:] = [ymin, ymax] - if self.axes._autoscaleXon: + if self.axes.get_autoscalex_on(): self.axes.set_xlim((xmin, xmax), auto=None) - if self.axes._autoscaleYon: + if self.axes.get_autoscaley_on(): self.axes.set_ylim((ymin, ymax), auto=None) self.stale = True diff --git a/lib/mpl_toolkits/mplot3d/axes3d.py b/lib/mpl_toolkits/mplot3d/axes3d.py index 23a78199ab53..c19327ae9231 100644 --- a/lib/mpl_toolkits/mplot3d/axes3d.py +++ b/lib/mpl_toolkits/mplot3d/axes3d.py @@ -462,29 +462,8 @@ def get_axis_position(self): def update_datalim(self, xys, **kwargs): pass - def get_autoscale_on(self): - # docstring inherited - return super().get_autoscale_on() and self.get_autoscalez_on() - - def get_autoscalez_on(self): - """Return whether the z-axis is autoscaled.""" - return self._autoscaleZon - - def set_autoscale_on(self, b): - # docstring inherited - super().set_autoscale_on(b) - self.set_autoscalez_on(b) - - def set_autoscalez_on(self, b): - """ - Set whether the z-axis is autoscaled on the next draw or call to - `.Axes.autoscale_view`. - - Parameters - ---------- - b : bool - """ - self._autoscaleZon = b + get_autoscalez_on = _axis_method_wrapper("zaxis", "_get_autoscale_on") + set_autoscalez_on = _axis_method_wrapper("zaxis", "_set_autoscale_on") def set_zmargin(self, m): """ @@ -558,15 +537,18 @@ def autoscale(self, enable=True, axis='both', tight=None): scalez = True else: if axis in ['x', 'both']: - self._autoscaleXon = scalex = bool(enable) + self.set_autoscalex_on(bool(enable)) + scalex = self.get_autoscalex_on() else: scalex = False if axis in ['y', 'both']: - self._autoscaleYon = scaley = bool(enable) + self.set_autoscaley_on(bool(enable)) + scaley = self.get_autoscaley_on() else: scaley = False if axis in ['z', 'both']: - self._autoscaleZon = scalez = bool(enable) + self.set_autoscalez_on(bool(enable)) + scalez = self.get_autoscalez_on() else: scalez = False if scalex: @@ -613,7 +595,7 @@ def autoscale_view(self, tight=None, scalex=True, scaley=True, else: _tight = self._tight = bool(tight) - if scalex and self._autoscaleXon: + if scalex and self.get_autoscalex_on(): self._shared_axes["x"].clean() x0, x1 = self.xy_dataLim.intervalx xlocator = self.xaxis.get_major_locator() @@ -626,7 +608,7 @@ def autoscale_view(self, tight=None, scalex=True, scaley=True, x0, x1 = xlocator.view_limits(x0, x1) self.set_xbound(x0, x1) - if scaley and self._autoscaleYon: + if scaley and self.get_autoscaley_on(): self._shared_axes["y"].clean() y0, y1 = self.xy_dataLim.intervaly ylocator = self.yaxis.get_major_locator() @@ -639,7 +621,7 @@ def autoscale_view(self, tight=None, scalex=True, scaley=True, y0, y1 = ylocator.view_limits(y0, y1) self.set_ybound(y0, y1) - if scalez and self._autoscaleZon: + if scalez and self.get_autoscalez_on(): self._shared_axes["z"].clean() z0, z1 = self.zz_dataLim.intervalx zlocator = self.zaxis.get_major_locator() @@ -976,7 +958,7 @@ def cla(self): except TypeError: pass - self._autoscaleZon = True + self.set_autoscalez_on(True) if self._focal_length == np.inf: self._zmargin = rcParams['axes.zmargin'] else: