diff --git a/lib/matplotlib/axes/_base.py b/lib/matplotlib/axes/_base.py index edddd7a7f8a5..95a052461ac4 100644 --- a/lib/matplotlib/axes/_base.py +++ b/lib/matplotlib/axes/_base.py @@ -2185,6 +2185,10 @@ def autoscale(self, enable=True, axis='both', tight=None): if axis in ['y', 'both']: self._autoscaleYon = bool(enable) scaley = self._autoscaleYon + if tight and scalex: + self._xmargin = 0 + if tight and scaley: + self._ymargin = 0 self.autoscale_view(tight=tight, scalex=scalex, scaley=scaley) def autoscale_view(self, tight=None, scalex=True, scaley=True): @@ -2194,6 +2198,14 @@ def autoscale_view(self, tight=None, scalex=True, scaley=True): setting *scaley* to *False*. The autoscaling preserves any axis direction reversal that has already been done. + If *tight* is *False*, the axis major locator will be used + to expand the view limits if rcParams['axes.autolimit_mode'] + is 'round_numbers'. Note that any margins that are in effect + will be applied first, regardless of whether *tight* is + *True* or *False*. Specifying *tight* as *True* or *False* + saves the setting as a private attribute of the Axes; specifying + it as *None* (the default) applies the previously saved value. + The data limits are not updated automatically when artist data are changed after the artist has been added to an Axes instance. In that case, use :meth:`matplotlib.axes.Axes.relim` prior to calling @@ -2246,52 +2258,56 @@ def autoscale_view(self, tight=None, scalex=True, scaley=True): def handle_single_axis(scale, autoscaleon, shared_axes, interval, minpos, axis, margin, do_lower_margin, do_upper_margin, set_bound): - if scale and autoscaleon: - shared = shared_axes.get_siblings(self) - dl = [ax.dataLim for ax in shared] - # ignore non-finite data limits if good limits exist - finite_dl = [d for d in dl if np.isfinite(d).all()] - if len(finite_dl): - dl = finite_dl - - bb = mtransforms.BboxBase.union(dl) - x0, x1 = getattr(bb, interval) - locator = axis.get_major_locator() - try: - # e.g., DateLocator has its own nonsingular() - x0, x1 = locator.nonsingular(x0, x1) - except AttributeError: - # Default nonsingular for, e.g., MaxNLocator - x0, x1 = mtransforms.nonsingular( - x0, x1, increasing=False, expander=0.05) - - if margin > 0 and (do_lower_margin or do_upper_margin): - if axis.get_scale() == 'linear': - delta = (x1 - x0) * margin - if do_lower_margin: - x0 -= delta - if do_upper_margin: - x1 += delta - else: - # If we have a non-linear scale, we need to - # add the margin in figure space and then - # transform back - minpos = getattr(bb, minpos) - transform = axis.get_transform() - inverse_trans = transform.inverted() - x0, x1 = axis._scale.limit_range_for_scale( - x0, x1, minpos) - x0t, x1t = transform.transform([x0, x1]) - delta = (x1t - x0t) * margin - if do_lower_margin: - x0t -= delta - if do_upper_margin: - x1t += delta - x0, x1 = inverse_trans.transform([x0t, x1t]) - - if not _tight: - x0, x1 = locator.view_limits(x0, x1) - set_bound(x0, x1) + + if not (scale and autoscaleon): + return # nothing to do... + + shared = shared_axes.get_siblings(self) + dl = [ax.dataLim for ax in shared] + # ignore non-finite data limits if good limits exist + finite_dl = [d for d in dl if np.isfinite(d).all()] + if len(finite_dl): + dl = finite_dl + + bb = mtransforms.BboxBase.union(dl) + x0, x1 = getattr(bb, interval) + locator = axis.get_major_locator() + try: + # e.g., DateLocator has its own nonsingular() + x0, x1 = locator.nonsingular(x0, x1) + except AttributeError: + # Default nonsingular for, e.g., MaxNLocator + x0, x1 = mtransforms.nonsingular( + x0, x1, increasing=False, expander=0.05) + + if margin > 0 and (do_lower_margin or do_upper_margin): + if axis.get_scale() == 'linear': + delta = (x1 - x0) * margin + if do_lower_margin: + x0 -= delta + if do_upper_margin: + x1 += delta + else: + # If we have a non-linear scale, we need to + # add the margin in figure space and then + # transform back + minpos = getattr(bb, minpos) + transform = axis.get_transform() + inverse_trans = transform.inverted() + x0, x1 = axis._scale.limit_range_for_scale( + x0, x1, minpos) + x0t, x1t = transform.transform([x0, x1]) + delta = (x1t - x0t) * margin + if do_lower_margin: + x0t -= delta + if do_upper_margin: + x1t += delta + x0, x1 = inverse_trans.transform([x0t, x1t]) + + if not _tight: + x0, x1 = locator.view_limits(x0, x1) + set_bound(x0, x1) + # End of definition of internal function 'handle_single_axis'. handle_single_axis( scalex, self._autoscaleXon, self._shared_x_axes, diff --git a/lib/matplotlib/tests/test_axes.py b/lib/matplotlib/tests/test_axes.py index 29ed50eaf6e3..0bcbaa492b45 100644 --- a/lib/matplotlib/tests/test_axes.py +++ b/lib/matplotlib/tests/test_axes.py @@ -167,6 +167,16 @@ def test_autoscale_tiny_range(): ax[i].plot([0, 1], [1, 1 + y1]) +@cleanup(style='default') +def test_autoscale_tight(): + fig, ax = plt.subplots(1, 1) + ax.plot([1, 2, 3, 4]) + ax.autoscale(enable=True, axis='x', tight=False) + ax.autoscale(enable=True, axis='y', tight=True) + assert_allclose(ax.get_xlim(), (-0.15, 3.15)) + assert_allclose(ax.get_ylim(), (1.0, 4.0)) + + @image_comparison(baseline_images=['offset_points'], remove_text=True) def test_basic_annotate(): pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy