From 167105fd14c6c9c5b5602f3faa3e66aa56853d57 Mon Sep 17 00:00:00 2001 From: Antony Lee Date: Sun, 9 Feb 2020 01:08:51 +0100 Subject: [PATCH] Fix interaction between sticky_edges and shared axes. --- lib/matplotlib/axes/_base.py | 27 +++++++++++++++++++-------- lib/matplotlib/tests/test_axes.py | 15 +++++++++++++++ 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/lib/matplotlib/axes/_base.py b/lib/matplotlib/axes/_base.py index c5aa98e5a3e6..0db3e4f88dab 100644 --- a/lib/matplotlib/axes/_base.py +++ b/lib/matplotlib/axes/_base.py @@ -2436,14 +2436,25 @@ def autoscale_view(self, tight=None, scalex=True, scaley=True): if tight is not None: self._tight = bool(tight) - if self.use_sticky_edges and ( - (self._xmargin and scalex and self._autoscaleXon) or - (self._ymargin and scaley and self._autoscaleYon)): - stickies = [artist.sticky_edges for artist in self.get_children()] - else: # Small optimization. - stickies = [] - x_stickies = np.sort([x for sticky in stickies for x in sticky.x]) - y_stickies = np.sort([y for sticky in stickies for y in sticky.y]) + x_stickies = y_stickies = np.array([]) + if self.use_sticky_edges: + # Only iterate over axes and artists if needed. The check for + # ``hasattr(ax, "lines")`` is necessary because this can be 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: + x_stickies = np.sort(np.concatenate([ + artist.sticky_edges.x + for ax in self._shared_x_axes.get_siblings(self) + if hasattr(ax, "lines") + for artist in ax.get_children()])) + if self._ymargin and scaley and self._autoscaleYon: + y_stickies = np.sort(np.concatenate([ + artist.sticky_edges.y + for ax in self._shared_y_axes.get_siblings(self) + if hasattr(ax, "lines") + for artist in ax.get_children()])) if self.get_xscale().lower() == 'log': x_stickies = x_stickies[x_stickies > 0] if self.get_yscale().lower() == 'log': diff --git a/lib/matplotlib/tests/test_axes.py b/lib/matplotlib/tests/test_axes.py index 8e8729751290..7791e8dd2622 100644 --- a/lib/matplotlib/tests/test_axes.py +++ b/lib/matplotlib/tests/test_axes.py @@ -398,6 +398,21 @@ def test_use_sticky_edges(): assert_allclose(ax.get_ylim(), (-0.5, 1.5)) +@check_figures_equal(extensions=["png"]) +def test_sticky_shared_axes(fig_test, fig_ref): + # Check that sticky edges work whether they are set in an axes that is a + # "master" in a share, or an axes that is a "follower". + Z = np.arange(15).reshape(3, 5) + + ax0 = fig_test.add_subplot(211) + ax1 = fig_test.add_subplot(212, sharex=ax0) + ax1.pcolormesh(Z) + + ax0 = fig_ref.add_subplot(212) + ax1 = fig_ref.add_subplot(211, sharex=ax0) + ax0.pcolormesh(Z) + + @image_comparison(['offset_points'], remove_text=True) def test_basic_annotate(): # Setup some data