Skip to content

Commit a0e7ae5

Browse files
jayaprajapatiimeeseeksmachine
authored andcommitted
Backport PR matplotlib#31304: Fix restoring 'auto' aspect in 3D axes after switching from 'equal'
1 parent 9001323 commit a0e7ae5

2 files changed

Lines changed: 66 additions & 1 deletion

File tree

lib/mpl_toolkits/mplot3d/axes3d.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,9 +339,28 @@ def set_aspect(self, aspect, adjustable=None, anchor=None, share=False):
339339
aspect=aspect)
340340

341341
self.set_adjustable(adjustable)
342+
343+
if self._aspect == 'auto' and aspect != 'auto':
344+
self._auto_aspect_restore_limits = list(self.get_w_lims())
345+
342346
self._aspect = aspect
343347

344-
if aspect in ('equal', 'equalxy', 'equalxz', 'equalyz'):
348+
if aspect == "auto":
349+
if self._adjustable == "box":
350+
self.set_box_aspect(None)
351+
352+
elif self._adjustable == "datalim":
353+
if hasattr(self, "_auto_aspect_restore_limits"):
354+
limits = self._auto_aspect_restore_limits
355+
356+
if limits[0] is not None:
357+
self.set_xlim3d(limits[0], limits[1], auto=True)
358+
if limits[2] is not None:
359+
self.set_ylim3d(limits[2], limits[3], auto=True)
360+
if limits[4] is not None:
361+
self.set_zlim3d(limits[4], limits[5], auto=True)
362+
del self._auto_aspect_restore_limits
363+
else:
345364
ax_indices = self._equal_aspect_axis_indices(aspect)
346365

347366
view_intervals = np.array([self.xaxis.get_view_interval(),
@@ -871,6 +890,11 @@ def _set_lim3d(self, axis, lower=None, upper=None, *, emit=True,
871890
delta = (upper - lower) * view_margin
872891
lower -= delta
873892
upper += delta
893+
894+
if not auto and hasattr(self, '_auto_aspect_restore_limits'):
895+
idx = {self.xaxis: 0, self.yaxis: 2, self.zaxis: 4}[axis]
896+
self._auto_aspect_restore_limits[idx] = None
897+
self._auto_aspect_restore_limits[idx + 1] = None
874898
return axis._set_lim(lower, upper, emit=emit, auto=auto)
875899

876900
def set_xlim(self, left=None, right=None, *, emit=True, auto=False,

lib/mpl_toolkits/mplot3d/tests/test_axes3d.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,47 @@ def test_axis_positions_inverted():
9898
ax.set(xlabel='x', ylabel='y', zlabel='z', title=title)
9999

100100

101+
def test_set_aspect_datalim_restores_limits():
102+
103+
fig = plt.figure()
104+
ax = fig.add_subplot(projection='3d')
105+
106+
ax.plot([0,1], [0,2], [0,3])
107+
108+
fig.canvas.draw()
109+
default_limits = ax.get_w_lims()
110+
111+
ax.set_aspect('equal', adjustable='datalim')
112+
fig.canvas.draw()
113+
equal_limits = ax.get_w_lims()
114+
115+
ax.set_aspect('auto', adjustable='datalim')
116+
fig.canvas.draw()
117+
final_limits = ax.get_w_lims()
118+
119+
# equal should change limits
120+
assert not np.allclose(default_limits, equal_limits)
121+
122+
# auto should restore original limits
123+
assert np.allclose(default_limits, final_limits)
124+
125+
126+
def test_set_aspect_datalim_restores_untouched_axes():
127+
fig = plt.figure()
128+
ax = fig.add_subplot(projection='3d')
129+
ax.plot([1, 2], [3, 4], [5, 6])
130+
orig_lims = ax.get_w_lims()
131+
132+
ax.set_aspect('equal', adjustable='datalim')
133+
ax.set_xlim(-50, 50) # explicit user change mid-'equal'
134+
ax.set_aspect('auto', adjustable='datalim')
135+
136+
xlim, ylim, zlim = ax.get_xlim3d(), ax.get_ylim3d(), ax.get_zlim3d()
137+
assert xlim == (-50, 50) # explicit value preserved
138+
assert ylim == orig_lims[2:4] # untouched axis restored
139+
assert zlim == orig_lims[4:6] # untouched axis restored
140+
141+
101142
@mpl3d_image_comparison(['aspects.png'], remove_text=False, style='mpl20')
102143
def test_aspects():
103144
aspects = ('auto', 'equal', 'equalxy', 'equalyz', 'equalxz', 'equal')

0 commit comments

Comments
 (0)