From 7c778f96110c424b9c7c405e3909d0e904bca79f Mon Sep 17 00:00:00 2001 From: dkl <> Date: Sat, 18 Jul 2026 15:57:28 -0400 Subject: [PATCH 1/6] _set_scale emit flag --- lib/matplotlib/axis.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/lib/matplotlib/axis.py b/lib/matplotlib/axis.py index 349e728ba8ff..04941fdfbde8 100644 --- a/lib/matplotlib/axis.py +++ b/lib/matplotlib/axis.py @@ -832,7 +832,7 @@ def get_scale(self): """Return this Axis' scale (as a str).""" return self._scale.name - def _set_scale(self, value, **kwargs): + def _set_scale(self, value, *, emit=False, **kwargs): if not isinstance(value, mscale.ScaleBase): self._scale = mscale.scale_factory(value, self, **kwargs) else: @@ -844,6 +844,19 @@ def _set_scale(self, value, **kwargs): self.isDefault_majfmt = True self.isDefault_minfmt = True + if emit: + # Call all of the other Axes that are shared with this one + name = self._get_axis_name() + # TODO: is there a scale_changed callback? + for other in self._get_shared_axes(): + if other is self.axes: + continue + other._axis_map[name]._set_scale(value, emit=False, **kwargs) + # TODO: ditto + if ((other_fig := other.get_figure(root=False)) != + self.get_figure(root=False)): + other_fig.canvas.draw_idle() + # This method is directly wrapped by Axes.set_{x,y}scale. def _set_axes_scale(self, value, **kwargs): """ @@ -960,7 +973,7 @@ def clear(self): self._init() - self._set_scale('linear') + self._set_scale('linear', emit=True) # Clear the callback registry for this axis, or it may "leak" self.callbacks = cbook.CallbackRegistry(signals=["units"]) From a7da0bb528557e2e6f8f70c9a7bafe035998bca8 Mon Sep 17 00:00:00 2001 From: dkl <> Date: Sat, 18 Jul 2026 16:05:43 -0400 Subject: [PATCH 2/6] less invasive way, just in clear --- lib/matplotlib/axes/_base.py | 6 ++++++ lib/matplotlib/axis.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/matplotlib/axes/_base.py b/lib/matplotlib/axes/_base.py index c687bee313f8..e0c5fdfba8c5 100644 --- a/lib/matplotlib/axes/_base.py +++ b/lib/matplotlib/axes/_base.py @@ -1356,6 +1356,12 @@ def __clear(self): for axis in self._axis_map.values(): axis.clear() # Also resets the scale to linear. + # also need to do any shared axes + name = axis._get_axis_name() + for other in axis._get_shared_axes(): + if other is self.axes: + continue + other._axis_map[name]._set_scale("linear") for spine in self.spines.values(): spine._clear() # Use _clear to not clear Axis again diff --git a/lib/matplotlib/axis.py b/lib/matplotlib/axis.py index 04941fdfbde8..994166c1987d 100644 --- a/lib/matplotlib/axis.py +++ b/lib/matplotlib/axis.py @@ -973,7 +973,7 @@ def clear(self): self._init() - self._set_scale('linear', emit=True) + self._set_scale('linear') # Clear the callback registry for this axis, or it may "leak" self.callbacks = cbook.CallbackRegistry(signals=["units"]) From 6e2cf425d55f5a77df107005c727d453c5bd49b8 Mon Sep 17 00:00:00 2001 From: dkl <> Date: Sat, 18 Jul 2026 16:52:06 -0400 Subject: [PATCH 3/6] removed _set_scale change --- lib/matplotlib/axis.py | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/lib/matplotlib/axis.py b/lib/matplotlib/axis.py index 994166c1987d..349e728ba8ff 100644 --- a/lib/matplotlib/axis.py +++ b/lib/matplotlib/axis.py @@ -832,7 +832,7 @@ def get_scale(self): """Return this Axis' scale (as a str).""" return self._scale.name - def _set_scale(self, value, *, emit=False, **kwargs): + def _set_scale(self, value, **kwargs): if not isinstance(value, mscale.ScaleBase): self._scale = mscale.scale_factory(value, self, **kwargs) else: @@ -844,19 +844,6 @@ def _set_scale(self, value, *, emit=False, **kwargs): self.isDefault_majfmt = True self.isDefault_minfmt = True - if emit: - # Call all of the other Axes that are shared with this one - name = self._get_axis_name() - # TODO: is there a scale_changed callback? - for other in self._get_shared_axes(): - if other is self.axes: - continue - other._axis_map[name]._set_scale(value, emit=False, **kwargs) - # TODO: ditto - if ((other_fig := other.get_figure(root=False)) != - self.get_figure(root=False)): - other_fig.canvas.draw_idle() - # This method is directly wrapped by Axes.set_{x,y}scale. def _set_axes_scale(self, value, **kwargs): """ From 1403215cfee430606674d23cff6f5d4da38e6258 Mon Sep 17 00:00:00 2001 From: dkl <> Date: Sun, 19 Jul 2026 08:50:18 -0400 Subject: [PATCH 4/6] added test --- lib/matplotlib/axes/_base.py | 2 +- lib/matplotlib/tests/test_axes.py | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/lib/matplotlib/axes/_base.py b/lib/matplotlib/axes/_base.py index e0c5fdfba8c5..0bcd926a56e8 100644 --- a/lib/matplotlib/axes/_base.py +++ b/lib/matplotlib/axes/_base.py @@ -1356,7 +1356,7 @@ def __clear(self): for axis in self._axis_map.values(): axis.clear() # Also resets the scale to linear. - # also need to do any shared axes + # need to do any shared axis scales as well name = axis._get_axis_name() for other in axis._get_shared_axes(): if other is self.axes: diff --git a/lib/matplotlib/tests/test_axes.py b/lib/matplotlib/tests/test_axes.py index 3189076c7655..eded4165dbc4 100644 --- a/lib/matplotlib/tests/test_axes.py +++ b/lib/matplotlib/tests/test_axes.py @@ -37,6 +37,7 @@ from matplotlib.projections.geo import HammerAxes from matplotlib.projections.polar import PolarAxes import matplotlib.pyplot as plt +import matplotlib.scale as mscales import matplotlib.text as mtext import matplotlib.ticker as mticker import matplotlib.transforms as mtransforms @@ -9308,6 +9309,23 @@ def test_shared_axes_clear(fig_test, fig_ref): ax.plot(x, y) +def test_shared_axes_clear_scale(): + _, axs = plt.subplots(1, 2, sharey=True) + x = range(1, 10) + axs[0].loglog(x, x) + axs[1].loglog(x, x) + axs[0].clear() + + # the cleared axes has linear on both axis + for axis in axs[0]._axis_map.values(): + assert isinstance(axis._scale, mscales.LinearScale) + + # the linked axes becomes linear on the shared y-axis + assert isinstance(axs[1].xaxis._scale, mscales.LogScale) + assert isinstance(axs[1].yaxis._scale, mscales.LinearScale) + + + def test_shared_axes_retick(): fig, axs = plt.subplots(2, 2, sharex='all', sharey='all') From 4c1987e11b170aa887955c1a82af9be4792ca554 Mon Sep 17 00:00:00 2001 From: dkl <> Date: Sun, 19 Jul 2026 09:16:59 -0400 Subject: [PATCH 5/6] recwarn --- lib/matplotlib/tests/test_axes.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/matplotlib/tests/test_axes.py b/lib/matplotlib/tests/test_axes.py index eded4165dbc4..31180b7b91f8 100644 --- a/lib/matplotlib/tests/test_axes.py +++ b/lib/matplotlib/tests/test_axes.py @@ -9309,13 +9309,15 @@ def test_shared_axes_clear(fig_test, fig_ref): ax.plot(x, y) -def test_shared_axes_clear_scale(): +def test_shared_axes_clear_scale(recwarn): _, axs = plt.subplots(1, 2, sharey=True) x = range(1, 10) axs[0].loglog(x, x) axs[1].loglog(x, x) axs[0].clear() + assert len(recwarn) == 0 + # the cleared axes has linear on both axis for axis in axs[0]._axis_map.values(): assert isinstance(axis._scale, mscales.LinearScale) From 7be82a456860d8175f3ef88cc3e0e47f1fef79be Mon Sep 17 00:00:00 2001 From: dkl <> Date: Tue, 21 Jul 2026 20:22:42 -0400 Subject: [PATCH 6/6] axis_map.values -> items() --- lib/matplotlib/axes/_base.py | 3 +-- lib/matplotlib/tests/test_axes.py | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/matplotlib/axes/_base.py b/lib/matplotlib/axes/_base.py index 0bcd926a56e8..c972c3febb6e 100644 --- a/lib/matplotlib/axes/_base.py +++ b/lib/matplotlib/axes/_base.py @@ -1354,10 +1354,9 @@ def __clear(self): xaxis_visible = self.xaxis.get_visible() yaxis_visible = self.yaxis.get_visible() - for axis in self._axis_map.values(): + for name, axis in self._axis_map.items(): axis.clear() # Also resets the scale to linear. # need to do any shared axis scales as well - name = axis._get_axis_name() for other in axis._get_shared_axes(): if other is self.axes: continue diff --git a/lib/matplotlib/tests/test_axes.py b/lib/matplotlib/tests/test_axes.py index 31180b7b91f8..8102163b24b5 100644 --- a/lib/matplotlib/tests/test_axes.py +++ b/lib/matplotlib/tests/test_axes.py @@ -9327,7 +9327,6 @@ def test_shared_axes_clear_scale(recwarn): assert isinstance(axs[1].yaxis._scale, mscales.LinearScale) - def test_shared_axes_retick(): fig, axs = plt.subplots(2, 2, sharex='all', sharey='all')