Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 2e8231f

Browse files
Standardize edge-on axis locations when viewing primary 3d axis planes (#23644)
* Put edge-on axes on left and right when viewing 3d axis planes Tests Fix broken tests Clean up test Co-authored-by: Elliott Sales de Andrade <[email protected]>
1 parent 04952fe commit 2e8231f

File tree

4 files changed

+43
-10
lines changed

4 files changed

+43
-10
lines changed

lib/mpl_toolkits/mplot3d/axis3d.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -244,11 +244,23 @@ def _get_coord_info(self, renderer):
244244
bounds_proj = self.axes.tunit_cube(bounds, self.axes.M)
245245

246246
# Determine which one of the parallel planes are higher up:
247-
highs = np.zeros(3, dtype=bool)
247+
means_z0 = np.zeros(3)
248+
means_z1 = np.zeros(3)
248249
for i in range(3):
249-
mean_z0 = np.mean(bounds_proj[self._PLANES[2 * i], 2])
250-
mean_z1 = np.mean(bounds_proj[self._PLANES[2 * i + 1], 2])
251-
highs[i] = mean_z0 < mean_z1
250+
means_z0[i] = np.mean(bounds_proj[self._PLANES[2 * i], 2])
251+
means_z1[i] = np.mean(bounds_proj[self._PLANES[2 * i + 1], 2])
252+
highs = means_z0 < means_z1
253+
254+
# Special handling for edge-on views
255+
equals = np.abs(means_z0 - means_z1) <= np.finfo(float).eps
256+
if np.sum(equals) == 2:
257+
vertical = np.where(~equals)[0][0]
258+
if vertical == 2: # looking at XY plane
259+
highs = np.array([True, True, highs[2]])
260+
elif vertical == 1: # looking at XZ plane
261+
highs = np.array([True, highs[1], False])
262+
elif vertical == 0: # looking at YZ plane
263+
highs = np.array([highs[0], False, False])
252264

253265
return mins, maxs, centers, deltas, bounds_proj, highs
254266

lib/mpl_toolkits/tests/test_mplot3d.py

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,27 @@ def test_axes3d_repr():
6060
"title={'center': 'title'}, xlabel='x', ylabel='y', zlabel='z'>")
6161

6262

63+
@mpl3d_image_comparison(['axes3d_primary_views.png'])
64+
def test_axes3d_primary_views():
65+
# (elev, azim, roll)
66+
views = [(90, -90, 0), # XY
67+
(0, -90, 0), # XZ
68+
(0, 0, 0), # YZ
69+
(-90, 90, 0), # -XY
70+
(0, 90, 0), # -XZ
71+
(0, 180, 0)] # -YZ
72+
# When viewing primary planes, draw the two visible axes so they intersect
73+
# at their low values
74+
fig, axs = plt.subplots(2, 3, subplot_kw={'projection': '3d'})
75+
for i, ax in enumerate(axs.flat):
76+
ax.set_xlabel('x')
77+
ax.set_ylabel('y')
78+
ax.set_zlabel('z')
79+
ax.set_proj_type('ortho')
80+
ax.view_init(elev=views[i][0], azim=views[i][1], roll=views[i][2])
81+
plt.tight_layout()
82+
83+
6384
@mpl3d_image_comparison(['bar3d.png'])
6485
def test_bar3d():
6586
fig = plt.figure()
@@ -1846,9 +1867,9 @@ def test_scatter_spiral():
18461867
[0.0, 0.0, -1.142857, 10.571429],
18471868
],
18481869
[
1849-
([0.06329114, -0.06329114], [-0.04746835, -0.04746835]),
1850-
([-0.06329114, -0.06329114], [0.04746835, -0.04746835]),
1851-
([0.05617978, 0.06329114], [-0.04213483, -0.04746835]),
1870+
([-0.06329114, 0.06329114], [0.04746835, 0.04746835]),
1871+
([0.06329114, 0.06329114], [-0.04746835, 0.04746835]),
1872+
([-0.05617978, -0.06329114], [0.04213483, 0.04746835]),
18521873
],
18531874
[2, 2, 0],
18541875
),
@@ -1861,9 +1882,9 @@ def test_scatter_spiral():
18611882
[0.0, -1.142857, 0.0, 10.571429],
18621883
],
18631884
[
1864-
([-0.06329114, -0.06329114], [-0.04746835, 0.04746835]),
1865-
([0.06329114, 0.05617978], [-0.04746835, -0.04213483]),
1866-
([0.06329114, -0.06329114], [-0.04746835, -0.04746835]),
1885+
([-0.06329114, -0.06329114], [0.04746835, -0.04746835]),
1886+
([0.06329114, 0.05617978], [0.04746835, 0.04213483]),
1887+
([0.06329114, -0.06329114], [0.04746835, 0.04746835]),
18671888
],
18681889
[1, 2, 1],
18691890
),

0 commit comments

Comments
 (0)