-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Surprising/changed axis limit (autoscale) behavior #17331
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Is "autoscaling" actually documented anywhere? https://matplotlib.org/3.1.1/api/_as_gen/matplotlib.pyplot.autoscale.html just says "turn autoscaling on or off" but that's a bit tautological: it's saying "function f does f". What effect does f have? |
https://matplotlib.org/api/_as_gen/matplotlib.axes.Axes.autoscale_view.html is the method that actually does the rescaling and has a slightly better explaination. This also gets coupled with "margins" and "sticky edges" https://matplotlib.org/gallery/subplots_axes_and_figures/axes_margins.html. I suspect that this related to making the auto-scaling lazier. On master I get a flash of the wrong scaling before it goes to the correct limits but it is still broken an v3.2.x. I suspect the problem is that adding the scatter "arms" the rescale, but setting the ylim does not "disarm" it. If you force a |
This only happens w/ What did |
No, I'm asking for the y axis limits to be
Yes. My understanding, and the previous behavior, is that the
Why is that super confusing? If I am calling a method to set explicit limits, I don't think matplotlib should ignore my limits and autoscale to narrower values. |
I guess diff --git i/lib/matplotlib/axes/_base.py w/lib/matplotlib/axes/_base.py
index 8f60cfedd..bd727a529 100644
--- i/lib/matplotlib/axes/_base.py
+++ w/lib/matplotlib/axes/_base.py
@@ -3331,6 +3331,9 @@ class _AxesBase(martist.Artist):
left, right = sorted([left, right], reverse=bool(reverse))
self._viewLim.intervalx = (left, right)
+ # Mark viewlims as no longer stale without triggering an autoscale.
+ for ax in self._shared_x_axes.get_siblings(self):
+ ax._stale_viewlim_x = False
if auto is not None:
self._autoscaleXon = bool(auto)
@@ -3600,6 +3603,9 @@ class _AxesBase(martist.Artist):
bottom, top = sorted([bottom, top], reverse=bool(reverse))
self._viewLim.intervaly = (bottom, top)
+ # Mark viewlims as no longer stale without triggering an autoscale.
+ for ax in self._shared_y_axes.get_siblings(self):
+ ax._stale_viewlim_y = False
if auto is not None:
self._autoscaleYon = bool(auto) is what we need, can you confirm that works for you? |
I agree, but then to autoscale if I add something new is surprising. I can see that its a useful feature, but it adds some complexity to the state of the plot that we have to keep track of, and obviously got dropped here. @anntzer, your patch appears to work for me. But I guess we need to test this flag better. |
Well the reason seaborn uses |
What I really want from explicit limits / autoscaling is something closer to a ratchet: I want to set limits that won't hide to-be-added data that lie outside of the limits but will also not contract when to-be-added data lie inside the limits (minus the margin). But I'd settle for some better/less tautological documentation for how autoscale is supposed to work :) |
@mwaskom I agree, that would be great. Until such a dream is realized I found that I could get satisfactory results like so: # for ylims only
cur_ylims = ax.get_ylim()
ax.relim()
new_lims = [ax.dataLim.y0, ax.dataLim.y0+ax.dataLim.height]
new_lims = [
new_lims[0] if new_lims[0]<cur_ylims[0] else cur_ylims[0],
new_lims[1] if new_lims[1]>cur_ylims[1] else cur_ylims[1]
]
ax.set_ylim(new_lims) Full code + associated |
@ianhi cleaner to write that code as ax.set_ylim(min(new_lims[0], cur_ylims[0]), max(new_lims[1], cur_ylims[1])) |
Bug report
Bug summary
The interaction of setting axis limits and autoscaling changed in 3.2 with little guidance, introducing unexpected behavior that doesn't always make sense.
Code for reproduction
Here is a plot that looks very different on 3.1.2 and 3.2.1
Actual outcome
On 3.2.1
Expected outcome
On 3.1.2
Matplotlib version
print(matplotlib.get_backend())
): pylab inlineThe text was updated successfully, but these errors were encountered: