X Tutup
Skip to content
53 changes: 27 additions & 26 deletions lib/matplotlib/axes/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -2394,35 +2394,34 @@ def add_collection(self, collection, autolim=True):
collection.set_clip_path(self.patch)

if autolim:
# Make sure viewLim is not stale (mostly to match
# pre-lazy-autoscale behavior, which is not really better).
self._unstale_viewLim()
datalim = collection.get_datalim(self.transData)
points = datalim.get_points()
if not np.isinf(datalim.minpos).all():
# By definition, if minpos (minimum positive value) is set
# (i.e., non-inf), then min(points) <= minpos <= max(points),
# and minpos would be superfluous. However, we add minpos to
# the call so that self.dataLim will update its own minpos.
# This ensures that log scales see the correct minimum.
points = np.concatenate([points, [datalim.minpos]])
# only update the dataLim for x/y if the collection uses transData
# in this direction.
x_is_data, y_is_data = (collection.get_transform()
.contains_branch_separately(self.transData))
ox_is_data, oy_is_data = (collection.get_offset_transform()
.contains_branch_separately(self.transData))
self.update_datalim(
points,
updatex=x_is_data or ox_is_data,
updatey=y_is_data or oy_is_data,
)
self._update_collection_limits(collection)

if autolim != "_datalim_only":
self._request_autoscale_view()
self._request_autoscale_view()

self.stale = True
return collection

def _update_collection_limits(self, collection):
self._unstale_viewLim()

datalim = collection.get_datalim(self.transData)
points = datalim.get_points()

if not np.isinf(datalim.minpos).all():
points = np.concatenate([points, [datalim.minpos]])

transform = collection.get_transform()
offset_trf = collection.get_offset_transform()

x_is_data, y_is_data = transform.contains_branch_separately(self.transData)
ox_is_data, oy_is_data = offset_trf.contains_branch_separately(self.transData)

updatex = x_is_data or ox_is_data
updatey = y_is_data or oy_is_data

self.update_datalim(points, updatex=updatex, updatey=updatey)

def add_image(self, image):
"""
Add an `.AxesImage` to the Axes; return the image.
Expand Down Expand Up @@ -2641,14 +2640,16 @@ def relim(self, visible_only=False):

for artist in self._children:
if not visible_only or artist.get_visible():
if not artist._get_in_autoscale():
continue
if hasattr(artist, "get_in_autoscale") and not artist.get_in_autoscale(): # noqa: E501
continue
if isinstance(artist, mlines.Line2D):
self._update_line_limits(artist)
elif isinstance(artist, mpatches.Patch):
self._update_patch_limits(artist)
elif isinstance(artist, mimage.AxesImage):
self._update_image_limits(artist)
elif isinstance(artist, mcoll.Collection):
self._update_collection_limits(artist)

def update_datalim(self, xys, updatex=True, updatey=True):
"""
Expand Down
21 changes: 21 additions & 0 deletions lib/matplotlib/tests/test_axes.py
Original file line number Diff line number Diff line change
Expand Up @@ -10189,3 +10189,24 @@ def test_errorbar_uses_rcparams():
assert_allclose([cap.get_markeredgewidth() for cap in caplines], 2.5)
for barcol in barlinecols:
assert_allclose(barcol.get_linewidths(), 1.75)


def test_relim_updates_scatter_offsets():
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
Loading
X Tutup