diff --git a/lib/matplotlib/axes/_base.py b/lib/matplotlib/axes/_base.py index f89c231815dc..9e515a7a8aa0 100644 --- a/lib/matplotlib/axes/_base.py +++ b/lib/matplotlib/axes/_base.py @@ -29,6 +29,7 @@ import matplotlib.text as mtext import matplotlib.ticker as mticker import matplotlib.transforms as mtransforms +import matplotlib.collections as mcollections _log = logging.getLogger(__name__) @@ -2415,6 +2416,12 @@ def _update_image_limits(self, image): xmin, xmax, ymin, ymax = image.get_extent() self.axes.update_datalim(((xmin, ymin), (xmax, ymax))) + def _update_collection_limits(self, collection): + offsets = collection.get_offsets() + if offsets is not None and len(offsets): + self.update_datalim(offsets) + + def add_line(self, line): """ Add a `.Line2D` to the Axes; return the line. @@ -2605,6 +2612,8 @@ def relim(self, visible_only=False): self._update_patch_limits(artist) elif isinstance(artist, mimage.AxesImage): self._update_image_limits(artist) + elif isinstance(artist, mcollections.Collection): + self._update_collection_limits(artist) def update_datalim(self, xys, updatex=True, updatey=True): """ diff --git a/lib/matplotlib/tests/test_axes.py b/lib/matplotlib/tests/test_axes.py index 46843841fe93..6e6614090311 100644 --- a/lib/matplotlib/tests/test_axes.py +++ b/lib/matplotlib/tests/test_axes.py @@ -10159,3 +10159,27 @@ def test_animated_artists_not_drawn_by_default(): mocked_im_draw.assert_not_called() mocked_ln_draw.assert_not_called() + + +def test_relim_updates_scatter_offsets(): + import numpy as np + import matplotlib.pyplot as plt + + fig, ax = plt.subplots() + + xs = np.linspace(0, 10, 100) + ys = np.sin(xs) + scatter = ax.scatter(xs, ys) + + # Shift scatter upward + new_ys = np.sin(xs) + 5 + scatter.set_offsets(np.column_stack((xs, new_ys))) + + ax.relim() + ax.autoscale_view() + + ymin, ymax = ax.get_ylim() + + # New limits should reflect shifted data + assert ymin > 3 + assert ymax > 5