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

Skip to content

Commit 21f1177

Browse files
Switch tilt naming back to roll, flip rotation handedness
1 parent ef8d067 commit 21f1177

File tree

6 files changed

+50
-49
lines changed

6 files changed

+50
-49
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
3D plots gained a 3rd "tilt" viewing angle
1+
3D plots gained a 3rd "roll" viewing angle
22
------------------------------------------
33

4-
3D plots can now be viewed from any orientation with the addition of a 3rd tilt
4+
3D plots can now be viewed from any orientation with the addition of a 3rd roll
55
angle, which rotates the plot about the viewing axis. Interactive rotation
66
using the mouse still only controls elevation and azimuth, meaning that this
77
feature is relevant to users who create more complex camera angles
8-
programmatically. The default tilt angle of 0 is backwards-compatible with
8+
programmatically. The default roll angle of 0 is backwards-compatible with
99
existing 3D plots.
1010

1111
.. plot::
@@ -17,5 +17,5 @@ existing 3D plots.
1717
ax = fig.add_subplot(projection='3d')
1818
X, Y, Z = axes3d.get_test_data(0.05)
1919
ax.plot_wireframe(X, Y, Z, rstride=10, cstride=10)
20-
ax.view_init(elev=0, azim=0, tilt=30)
20+
ax.view_init(elev=0, azim=0, roll=30)
2121
plt.show()

examples/mplot3d/2dcollections3d.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,6 @@
4343

4444
# Customize the view angle so it's easier to see that the scatter points lie
4545
# on the plane y=0
46-
ax.view_init(elev=20., azim=-35, tilt=0)
46+
ax.view_init(elev=20., azim=-35, roll=0)
4747

4848
plt.show()

lib/mpl_toolkits/mplot3d/axes3d.py

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ class Axes3D(Axes):
5454

5555
def __init__(
5656
self, fig, rect=None, *args,
57-
elev=30, azim=-60, tilt=0, sharez=None, proj_type='persp',
57+
elev=30, azim=-60, roll=0, sharez=None, proj_type='persp',
5858
box_aspect=None, computed_zorder=True,
5959
**kwargs):
6060
"""
@@ -68,8 +68,8 @@ def __init__(
6868
Elevation viewing angle.
6969
azim : float, default: -60
7070
Azimuthal viewing angle.
71-
tilt : float, default: 0
72-
Tilt viewing angle.
71+
roll : float, default: 0
72+
Roll viewing angle.
7373
sharez : Axes3D, optional
7474
Other axes to share z-limits with.
7575
proj_type : {'persp', 'ortho'}
@@ -103,7 +103,7 @@ def __init__(
103103

104104
self.initial_azim = azim
105105
self.initial_elev = elev
106-
self.initial_tilt = tilt
106+
self.initial_roll = roll
107107
self.set_proj_type(proj_type)
108108
self.computed_zorder = computed_zorder
109109

@@ -115,7 +115,7 @@ def __init__(
115115

116116
# inhibit autoscale_view until the axes are defined
117117
# they can't be defined until Axes.__init__ has been called
118-
self.view_init(self.initial_elev, self.initial_azim, self.initial_tilt)
118+
self.view_init(self.initial_elev, self.initial_azim, self.initial_roll)
119119

120120
self._sharez = sharez
121121
if sharez is not None:
@@ -979,7 +979,7 @@ def clabel(self, *args, **kwargs):
979979
"""Currently not implemented for 3D axes, and returns *None*."""
980980
return None
981981

982-
def view_init(self, elev=None, azim=None, tilt=None, vertical_axis="z"):
982+
def view_init(self, elev=None, azim=None, roll=None, vertical_axis="z"):
983983
"""
984984
Set the elevation and azimuth of the axes in degrees (not radians).
985985
@@ -995,8 +995,8 @@ def view_init(self, elev=None, azim=None, tilt=None, vertical_axis="z"):
995995
The azimuth angle in the horizontal plane in degrees.
996996
If None then the initial value as specified in the `Axes3D`
997997
constructor is used.
998-
tilt : float, default: None
999-
The tilt angle about the viewing direction in degrees.
998+
roll : float, default: None
999+
The roll angle about the viewing direction in degrees.
10001000
If None then the initial value as specified in the `Axes3D`
10011001
constructor is used.
10021002
vertical_axis : {"z", "x", "y"}, default: "z"
@@ -1015,10 +1015,10 @@ def view_init(self, elev=None, azim=None, tilt=None, vertical_axis="z"):
10151015
else:
10161016
self.azim = azim
10171017

1018-
if tilt is None:
1019-
self.tilt = self.initial_tilt
1018+
if roll is None:
1019+
self.roll = self.initial_roll
10201020
else:
1021-
self.tilt = tilt
1021+
self.roll = roll
10221022

10231023
self._vertical_axis = _api.check_getitem(
10241024
dict(x=0, y=1, z=2), vertical_axis=vertical_axis
@@ -1058,10 +1058,10 @@ def get_proj(self):
10581058

10591059
# elev stores the elevation angle in the z plane
10601060
# azim stores the azimuth angle in the x,y plane
1061-
# tilt stores the tilt angle about the view axis
1061+
# roll stores the roll angle about the view axis
10621062
elev_rad = np.deg2rad(art3d._norm_angle(self.elev))
10631063
azim_rad = np.deg2rad(art3d._norm_angle(self.azim))
1064-
tilt_rad = np.deg2rad(art3d._norm_angle(self.tilt))
1064+
roll_rad = np.deg2rad(art3d._norm_angle(self.roll))
10651065

10661066
# Coordinates for a point that rotates around the box of data.
10671067
# p0, p1 corresponds to rotating the box only around the
@@ -1091,7 +1091,7 @@ def get_proj(self):
10911091
V = np.zeros(3)
10921092
V[self._vertical_axis] = -1 if abs(elev_rad) > 0.5 * np.pi else 1
10931093

1094-
viewM = proj3d.view_transformation(eye, R, V, tilt_rad)
1094+
viewM = proj3d.view_transformation(eye, R, V, roll_rad)
10951095
projM = self._projection(-self.dist, self.dist)
10961096
M0 = np.dot(viewM, worldM)
10971097
M = np.dot(projM, M0)
@@ -1179,15 +1179,15 @@ def _button_release(self, event):
11791179
def _get_view(self):
11801180
# docstring inherited
11811181
return (self.get_xlim(), self.get_ylim(), self.get_zlim(),
1182-
self.elev, self.azim, self.tilt)
1182+
self.elev, self.azim, self.roll)
11831183

11841184
def _set_view(self, view):
11851185
# docstring inherited
1186-
xlim, ylim, zlim, elev, azim, tilt = view
1186+
xlim, ylim, zlim, elev, azim, roll = view
11871187
self.set(xlim=xlim, ylim=ylim, zlim=zlim)
11881188
self.elev = elev
11891189
self.azim = azim
1190-
self.tilt = tilt
1190+
self.roll = roll
11911191

11921192
def format_zdata(self, z):
11931193
"""
@@ -1216,10 +1216,10 @@ def format_coord(self, xd, yd):
12161216
# ignore xd and yd and display angles instead
12171217
norm_elev = art3d._norm_angle(self.elev)
12181218
norm_azim = art3d._norm_angle(self.azim)
1219-
norm_tilt = art3d._norm_angle(self.tilt)
1219+
norm_roll = art3d._norm_angle(self.roll)
12201220
return (f"elevation={norm_elev:.0f}\N{DEGREE SIGN}, "
12211221
f"azimuth={norm_azim:.0f}\N{DEGREE SIGN}, "
1222-
f"tilt={norm_tilt:.0f}\N{DEGREE SIGN}"
1222+
f"roll={norm_roll:.0f}\N{DEGREE SIGN}"
12231223
).replace("-", "\N{MINUS SIGN}")
12241224

12251225
# nearest edge
@@ -1273,9 +1273,9 @@ def _on_move(self, event):
12731273
if dx == 0 and dy == 0:
12741274
return
12751275

1276-
tilt = np.deg2rad(self.tilt)
1277-
delev = -(dy/h)*180*np.cos(tilt) - (dx/w)*180*np.sin(tilt)
1278-
dazim = +(dy/h)*180*np.sin(tilt) - (dx/w)*180*np.cos(tilt)
1276+
roll = np.deg2rad(self.roll)
1277+
delev = -(dy/h)*180*np.cos(roll) + (dx/w)*180*np.sin(roll)
1278+
dazim = -(dy/h)*180*np.sin(roll) - (dx/w)*180*np.cos(roll)
12791279
self.elev = self.elev + delev
12801280
self.azim = self.azim + dazim
12811281
self.get_proj()
@@ -3273,10 +3273,10 @@ def _extract_errs(err, data, lomask, himask):
32733273
quiversize = np.mean(np.diff(quiversize, axis=0))
32743274
# quiversize is now in Axes coordinates, and to convert back to data
32753275
# coordinates, we need to run it through the inverse 3D transform. For
3276-
# consistency, this uses a fixed elevation, azimuth, and tilt.
3277-
with cbook._setattr_cm(self, elev=0, azim=0, tilt=0):
3276+
# consistency, this uses a fixed elevation, azimuth, and roll.
3277+
with cbook._setattr_cm(self, elev=0, azim=0, roll=0):
32783278
invM = np.linalg.inv(self.get_proj())
3279-
# elev=azim=tilt=0 produces the Y-Z plane, so quiversize in 2D 'x' is
3279+
# elev=azim=roll=0 produces the Y-Z plane, so quiversize in 2D 'x' is
32803280
# 'y' in 3D, hence the 1 index.
32813281
quiversize = np.dot(invM, np.array([quiversize, 0, 0, 0]))[1]
32823282
# Quivers use a fixed 15-degree arrow head, so scale up the length so

lib/mpl_toolkits/mplot3d/proj3d.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -68,18 +68,19 @@ def rotation_about_vector(v, angle):
6868
return R
6969

7070

71-
def view_transformation(E, R, V, tilt):
71+
def view_transformation(E, R, V, roll):
7272
n = (E - R)
7373
n = n/np.linalg.norm(n)
7474
u = np.cross(V, n)
7575
u = u/np.linalg.norm(u)
7676
v = np.cross(n, u) # Will be a unit vector
7777

78-
# Save some computation for the default tilt=0
79-
if tilt != 0:
80-
Rtilt = rotation_about_vector(n, tilt)
81-
u = np.dot(Rtilt, u)
82-
v = np.dot(Rtilt, v)
78+
# Save some computation for the default roll=0
79+
if roll != 0:
80+
# A positive rotation of the camera is a negative rotation of the world
81+
Rroll = rotation_about_vector(n, -roll)
82+
u = np.dot(Rroll, u)
83+
v = np.dot(Rroll, v)
8384

8485
Mr = np.eye(4)
8586
Mt = np.eye(4)

lib/mpl_toolkits/tests/test_mplot3d.py

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,9 @@ def test_bar3d_shaded():
6868
1, len(views),
6969
subplot_kw=dict(projection='3d')
7070
)
71-
for ax, (elev, azim, tilt) in zip(axs, views):
71+
for ax, (elev, azim, roll) in zip(axs, views):
7272
ax.bar3d(x2d, y2d, x2d * 0, 1, 1, z, shade=True)
73-
ax.view_init(elev=elev, azim=azim, tilt=tilt)
73+
ax.view_init(elev=elev, azim=azim, roll=roll)
7474
fig.canvas.draw()
7575

7676

@@ -387,10 +387,10 @@ def test_marker_draw_order_data_reversed(fig_test, fig_ref, azim):
387387
color = ['b', 'y']
388388
ax = fig_test.add_subplot(projection='3d')
389389
ax.scatter(x, y, z, s=3500, c=color)
390-
ax.view_init(elev=0, azim=azim, tilt=0)
390+
ax.view_init(elev=0, azim=azim, roll=0)
391391
ax = fig_ref.add_subplot(projection='3d')
392392
ax.scatter(x[::-1], y[::-1], z[::-1], s=3500, c=color[::-1])
393-
ax.view_init(elev=0, azim=azim, tilt=0)
393+
ax.view_init(elev=0, azim=azim, roll=0)
394394

395395

396396
@check_figures_equal(extensions=['png'])
@@ -410,11 +410,11 @@ def test_marker_draw_order_view_rotated(fig_test, fig_ref):
410410
# axis are not exactly invariant under 180 degree rotation -> deactivate
411411
ax.set_axis_off()
412412
ax.scatter(x, y, z, s=3500, c=color)
413-
ax.view_init(elev=0, azim=azim, tilt=0)
413+
ax.view_init(elev=0, azim=azim, roll=0)
414414
ax = fig_ref.add_subplot(projection='3d')
415415
ax.set_axis_off()
416416
ax.scatter(x, y, z, s=3500, c=color[::-1]) # color reversed
417-
ax.view_init(elev=0, azim=azim - 180, tilt=0) # view rotated by 180 deg
417+
ax.view_init(elev=0, azim=azim - 180, roll=0) # view rotated by 180 deg
418418

419419

420420
@mpl3d_image_comparison(['plot_3d_from_2d.png'], tol=0.015)
@@ -860,8 +860,8 @@ def _test_proj_make_M():
860860
E = np.array([1000, -1000, 2000])
861861
R = np.array([100, 100, 100])
862862
V = np.array([0, 0, 1])
863-
tilt = 0
864-
viewM = proj3d.view_transformation(E, R, V, tilt)
863+
roll = 0
864+
viewM = proj3d.view_transformation(E, R, V, roll)
865865
perspM = proj3d.persp_transformation(100, -100)
866866
M = np.dot(perspM, viewM)
867867
return M
@@ -926,8 +926,8 @@ def test_proj_axes_cube_ortho():
926926
E = np.array([200, 100, 100])
927927
R = np.array([0, 0, 0])
928928
V = np.array([0, 0, 1])
929-
tilt = 0
930-
viewM = proj3d.view_transformation(E, R, V, tilt)
929+
roll = 0
930+
viewM = proj3d.view_transformation(E, R, V, roll)
931931
orthoM = proj3d.ortho_transformation(-1, 1)
932932
M = np.dot(orthoM, viewM)
933933

@@ -1046,7 +1046,7 @@ def test_axes3d_isometric():
10461046
for s, e in combinations(np.array(list(product(r, r, r))), 2):
10471047
if abs(s - e).sum() == r[1] - r[0]:
10481048
ax.plot3D(*zip(s, e), c='k')
1049-
ax.view_init(elev=np.degrees(np.arctan(1. / np.sqrt(2))), azim=-45, tilt=0)
1049+
ax.view_init(elev=np.degrees(np.arctan(1. / np.sqrt(2))), azim=-45, roll=0)
10501050
ax.grid(True)
10511051

10521052

@@ -1598,7 +1598,7 @@ def test_computed_zorder():
15981598
linestyle='--',
15991599
color='green',
16001600
zorder=4)
1601-
ax.view_init(elev=20, azim=-20, tilt=0)
1601+
ax.view_init(elev=20, azim=-20, roll=0)
16021602
ax.axis('off')
16031603

16041604

@@ -1685,7 +1685,7 @@ def test_view_init_vertical_axis(
16851685
"""
16861686
rtol = 2e-06
16871687
ax = plt.subplot(1, 1, 1, projection="3d")
1688-
ax.view_init(elev=0, azim=0, tilt=0, vertical_axis=vertical_axis)
1688+
ax.view_init(elev=0, azim=0, roll=0, vertical_axis=vertical_axis)
16891689
ax.figure.canvas.draw()
16901690

16911691
# Assert the projection matrix:

0 commit comments

Comments
 (0)