Skip to content

set_{x,y,z}bound 3d limits are not persistent upon interactive rotation #18112

Closed

Description

@anntzer

Bug report

Bug summary

3D axes limits set using set_{x,y,z}bound are dropped when interactively rotating 3d axes.

Code for reproduction

import matplotlib.pyplot as plt

ax = plt.figure().add_subplot(projection="3d")
ax.plot([0, 1], [0, 1], [0, 1])
ax.set(xbound=[-1, 1], ybound=[-1, 1], zbound=[-1, 1])
# ax.set(xlim=[-1, 1], ylim=[-1, 1], zlim=[-1, 1])
plt.show()

then interactively rotate the axes with the mouse.

Actual outcome

The axes limits immediately snap back to [0, 1] (plus margins).

Expected outcome

Limits are respected (as with set_{x,y,z}lim).

Matplotlib version

  • Operating system: linux
  • Matplotlib version: master
  • Matplotlib backend (print(matplotlib.get_backend())): qt5agg
  • Python version: 38
  • Jupyter version (if applicable):
  • Other libraries:

Activity

  1. timhoffm commented on Jul 29, 2020

    @timhoffm
    Member

    The reason is the following

    set_x/y/zlim() deactivate autoscaling (auto=False). set_x/y/zbound() leave the autoscaling unchanged (calling set_xlim(auto=None)).

    This can be verified via

    ax.set(xbound=[-1, 1], ybound=[-1, 1], zbound=[-1, 1])
    ax._autoscaleXon = False
    ax._autoscaleYon = False
    ax._autoscaleZon = False
    

    fixing the issue.

    Questions:

    • Is it reasonable that *bounds and *lim behave differently concerning auto-scaling? But even if so, it may be hard to change, because I expect that would break a lot of user code.
    • Is there a reason that 3D rotation tries to auto-scale?
  2. added
    API: consistencyConsistency of the matplotlib API, including naming, behavior, defaults, …
    on Jul 29, 2020
  3. QuLogic commented on Jul 30, 2020

    @QuLogic
    Member

    It's not the mouse move that triggers it, it's the draw. If you insert fig.canvas.draw() before plt.show(), the limits are [0, 1]. I don't know why this change during draw is not reflected in the plot.

    I think this may be because of the new lazy autoscaling. Nothing in mplot3d sets the new ax._stale_viewlim_x, so _unstale_viewLim rescales.

  4. QuLogic commented on Jul 30, 2020

    @QuLogic
    Member

    This is a regression from 3.1.2; I will test some newer versions, but if it's lazy autoscaling, then it's a 3.3 3.2 regression. I think I've written most of a fix.

  5. added a commit that references this issue on Jul 30, 2020
    25986cd
  6. QuLogic commented on Jul 31, 2020

    @QuLogic
    Member

    I don't know why this change during draw is not reflected in the plot.

    And this is because Axes3D.draw first calculates the world projection, then calls super().draw(), and Axes.draw calls self._unstale_viewLim. Putting that at the beginning of Axes3D.draw makes things stabler. This is similar to #17422 for PolarAxes.

  7. added a commit that references this issue on Jul 31, 2020
    bce9c8d
  8. added a commit that references this issue on Aug 29, 2020
    242346d
  9. added a commit that references this issue on Dec 19, 2020
    cfb046e
  10. added this to the v3.4.0 milestone on Dec 25, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions