Axes Method - view_init¶
The view_init method sets the elevation and azimuth angles for viewing a 3D plot. It controls the camera position relative to the plotted surface.
Understanding View Angles¶
The view is defined by two angles: - Elevation (elev): Angle above the xy-plane in degrees. 0° is edge-on, 90° is directly above. - Azimuth (azim): Rotation around the z-axis in degrees. Determines horizontal viewing direction.
Basic Usage¶
Set viewing angles after creating a 3D plot.
1. Default View¶
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(-2, 2, 30)
y = np.linspace(-2, 2, 30)
X, Y = np.meshgrid(x, y)
Z = X**2 + Y**2
fig, ax = plt.subplots(subplot_kw={'projection': '3d'})
ax.plot_surface(X, Y, Z, cmap='viridis')
plt.show()
2. Custom View¶
fig, ax = plt.subplots(subplot_kw={'projection': '3d'})
ax.plot_surface(X, Y, Z, cmap='viridis')
ax.view_init(elev=30, azim=45)
plt.show()
3. Top-Down View¶
fig, ax = plt.subplots(subplot_kw={'projection': '3d'})
ax.plot_surface(X, Y, Z, cmap='viridis')
ax.view_init(elev=90, azim=0)
plt.show()
Elevation Angle¶
Control the vertical viewing angle.
1. Low Elevation¶
fig, ax = plt.subplots(subplot_kw={'projection': '3d'})
ax.plot_surface(X, Y, Z, cmap='viridis')
ax.view_init(elev=10, azim=-60)
plt.show()
2. Medium Elevation¶
fig, ax = plt.subplots(subplot_kw={'projection': '3d'})
ax.plot_surface(X, Y, Z, cmap='viridis')
ax.view_init(elev=30, azim=-60)
plt.show()
3. High Elevation¶
fig, ax = plt.subplots(subplot_kw={'projection': '3d'})
ax.plot_surface(X, Y, Z, cmap='viridis')
ax.view_init(elev=60, azim=-60)
plt.show()
4. Elevation Comparison¶
fig, axes = plt.subplots(1, 4, figsize=(16, 4), subplot_kw={'projection': '3d'})
elevations = [0, 30, 60, 90]
for ax, elev in zip(axes, elevations):
ax.plot_surface(X, Y, Z, cmap='viridis')
ax.view_init(elev=elev, azim=-60)
ax.set_title(f'elev={elev}°')
plt.tight_layout()
plt.show()
Azimuth Angle¶
Control the horizontal rotation.
1. Front View¶
fig, ax = plt.subplots(subplot_kw={'projection': '3d'})
ax.plot_surface(X, Y, Z, cmap='viridis')
ax.view_init(elev=30, azim=0)
plt.show()
2. Side View¶
fig, ax = plt.subplots(subplot_kw={'projection': '3d'})
ax.plot_surface(X, Y, Z, cmap='viridis')
ax.view_init(elev=30, azim=90)
plt.show()
3. Azimuth Comparison¶
fig, axes = plt.subplots(1, 4, figsize=(16, 4), subplot_kw={'projection': '3d'})
azimuths = [0, 45, 90, 135]
for ax, azim in zip(axes, azimuths):
ax.plot_surface(X, Y, Z, cmap='viridis')
ax.view_init(elev=30, azim=azim)
ax.set_title(f'azim={azim}°')
plt.tight_layout()
plt.show()
4. Full Rotation¶
fig, axes = plt.subplots(2, 4, figsize=(16, 8), subplot_kw={'projection': '3d'})
azimuths = [0, 45, 90, 135, 180, 225, 270, 315]
for ax, azim in zip(axes.flat, azimuths):
ax.plot_surface(X, Y, Z, cmap='viridis')
ax.view_init(elev=30, azim=azim)
ax.set_title(f'azim={azim}°')
plt.tight_layout()
plt.show()
Standard Views¶
Common viewing angles for specific perspectives.
1. Isometric View¶
fig, ax = plt.subplots(subplot_kw={'projection': '3d'})
ax.plot_surface(X, Y, Z, cmap='viridis')
ax.view_init(elev=35, azim=45)
ax.set_title('Isometric View')
plt.show()
2. Top-Down View¶
fig, ax = plt.subplots(subplot_kw={'projection': '3d'})
ax.plot_surface(X, Y, Z, cmap='viridis')
ax.view_init(elev=90, azim=0)
ax.set_title('Top-Down View')
plt.show()
3. Side Profile¶
fig, ax = plt.subplots(subplot_kw={'projection': '3d'})
ax.plot_surface(X, Y, Z, cmap='viridis')
ax.view_init(elev=0, azim=0)
ax.set_title('Side Profile')
plt.show()
4. Standard Views Gallery¶
fig, axes = plt.subplots(2, 3, figsize=(15, 10), subplot_kw={'projection': '3d'})
views = [
(30, -60, 'Default'),
(90, 0, 'Top-Down'),
(0, 0, 'Front'),
(0, 90, 'Side'),
(35, 45, 'Isometric'),
(60, -45, 'High Angle')
]
for ax, (elev, azim, title) in zip(axes.flat, views):
ax.plot_surface(X, Y, Z, cmap='viridis')
ax.view_init(elev=elev, azim=azim)
ax.set_title(f'{title}\n(elev={elev}°, azim={azim}°)')
plt.tight_layout()
plt.show()
Bivariate Normal Distribution Views¶
Apply view_init to statistical distributions.
1. Correlation Comparison with Consistent View¶
from scipy import stats
n = 40
mu_1, mu_2 = 0, 0
sigma_1, sigma_2 = 1, 0.5
rho1, rho2, rho3 = 0.0, -0.8, 0.8
x = np.linspace(-3.0, 3.0, n)
y = np.linspace(-3.0, 3.0, n)
X, Y = np.meshgrid(x, y)
pos = np.empty(X.shape + (2,))
pos[:, :, 0] = X
pos[:, :, 1] = Y
Z = lambda rho: stats.multivariate_normal(
[mu_1, mu_2],
[[sigma_1, rho * sigma_1 * sigma_2],
[rho * sigma_1 * sigma_2, sigma_2]]
)
fig, (ax0, ax1, ax2) = plt.subplots(1, 3, figsize=(15, 5), subplot_kw={'projection': '3d'})
ax0.plot_surface(X, Y, Z(rho1).pdf(pos), cmap='viridis', linewidth=0)
ax0.set_xlabel('X axis')
ax0.set_ylabel('Y axis')
ax0.view_init(80, -90)
ax0.set_title(f'ρ = {rho1}')
ax1.plot_surface(X, Y, Z(rho2).pdf(pos), cmap='viridis', linewidth=0)
ax1.set_xlabel('X axis')
ax1.set_ylabel('Y axis')
ax1.view_init(80, -90)
ax1.set_title(f'ρ = {rho2}')
ax2.plot_surface(X, Y, Z(rho3).pdf(pos), cmap='viridis', linewidth=0)
ax2.set_xlabel('X axis')
ax2.set_ylabel('Y axis')
ax2.view_init(80, -90)
ax2.set_title(f'ρ = {rho3}')
plt.tight_layout()
plt.show()
2. Top View for Contour Effect¶
rv = stats.multivariate_normal([0, 0], [[1, 0.5], [0.5, 1]])
Z_norm = rv.pdf(pos)
fig, axes = plt.subplots(1, 2, figsize=(12, 5), subplot_kw={'projection': '3d'})
axes[0].plot_surface(X, Y, Z_norm, cmap='viridis')
axes[0].view_init(elev=30, azim=-60)
axes[0].set_title('3D Perspective')
axes[1].plot_surface(X, Y, Z_norm, cmap='viridis')
axes[1].view_init(elev=90, azim=0)
axes[1].set_title('Top View (Contour-like)')
plt.tight_layout()
plt.show()
Multiple Angles of Same Surface¶
1. Four-View Layout¶
Z = np.sin(np.sqrt(X**2 + Y**2))
fig, axes = plt.subplots(2, 2, figsize=(12, 10), subplot_kw={'projection': '3d'})
views = [(30, -60), (30, 60), (60, -60), (60, 60)]
labels = ['Front-Left', 'Front-Right', 'High-Left', 'High-Right']
for ax, (elev, azim), label in zip(axes.flat, views, labels):
ax.plot_surface(X, Y, Z, cmap='plasma')
ax.view_init(elev=elev, azim=azim)
ax.set_title(f'{label}\n(elev={elev}°, azim={azim}°)')
plt.tight_layout()
plt.show()
2. Rotating Views¶
fig, axes = plt.subplots(2, 3, figsize=(15, 10), subplot_kw={'projection': '3d'})
angles = range(0, 360, 60)
for ax, azim in zip(axes.flat, angles):
ax.plot_surface(X, Y, Z, cmap='coolwarm')
ax.view_init(elev=30, azim=azim)
ax.set_title(f'azim={azim}°')
plt.tight_layout()
plt.show()
Combined with Other 3D Settings¶
1. With Axis Labels¶
fig, ax = plt.subplots(subplot_kw={'projection': '3d'})
ax.plot_surface(X, Y, Z, cmap='viridis')
ax.view_init(elev=25, azim=45)
ax.set_xlabel('X axis')
ax.set_ylabel('Y axis')
ax.set_zlabel('Z axis')
plt.show()
2. With Title¶
fig, ax = plt.subplots(subplot_kw={'projection': '3d'})
ax.plot_surface(X, Y, Z, cmap='viridis')
ax.view_init(elev=35, azim=-45)
ax.set_title('Surface Plot with Custom View', fontsize=14)
plt.show()
3. With Colorbar¶
fig, ax = plt.subplots(figsize=(10, 8), subplot_kw={'projection': '3d'})
surf = ax.plot_surface(X, Y, Z, cmap='coolwarm')
ax.view_init(elev=30, azim=45)
fig.colorbar(surf, shrink=0.5, aspect=10)
plt.show()
Negative Elevation¶
View from below the surface.
1. Below Surface View¶
fig, ax = plt.subplots(subplot_kw={'projection': '3d'})
ax.plot_surface(X, Y, Z, cmap='viridis')
ax.view_init(elev=-30, azim=45)
ax.set_title('View from Below (elev=-30°)')
plt.show()
2. Above vs Below Comparison¶
fig, axes = plt.subplots(1, 2, figsize=(12, 5), subplot_kw={'projection': '3d'})
axes[0].plot_surface(X, Y, Z, cmap='viridis')
axes[0].view_init(elev=30, azim=45)
axes[0].set_title('Above (elev=30°)')
axes[1].plot_surface(X, Y, Z, cmap='viridis')
axes[1].view_init(elev=-30, azim=45)
axes[1].set_title('Below (elev=-30°)')
plt.tight_layout()
plt.show()
Practical Applications¶
1. Best View for Data Understanding¶
def f(X, Y):
return np.exp(-(X**2 + Y**2) / 2) / (2 * np.pi)
x = np.linspace(-3, 3, 50)
y = np.linspace(-3, 3, 50)
X, Y = np.meshgrid(x, y)
Z = f(X, Y)
fig, axes = plt.subplots(1, 3, figsize=(15, 5), subplot_kw={'projection': '3d'})
# 3D perspective
axes[0].plot_surface(X, Y, Z, cmap='viridis')
axes[0].view_init(elev=30, azim=-60)
axes[0].set_title('3D Shape')
# Top view for distribution spread
axes[1].plot_surface(X, Y, Z, cmap='viridis')
axes[1].view_init(elev=90, azim=0)
axes[1].set_title('Distribution Spread')
# Side view for peak height
axes[2].plot_surface(X, Y, Z, cmap='viridis')
axes[2].view_init(elev=0, azim=0)
axes[2].set_title('Peak Height')
plt.tight_layout()
plt.show()
2. Publication-Quality Figure¶
from scipy import stats
n = 60
x = np.linspace(-3, 3, n)
y = np.linspace(-3, 3, n)
X, Y = np.meshgrid(x, y)
pos = np.dstack((X, Y))
rv = stats.multivariate_normal([0, 0], [[1, 0.6], [0.6, 1]])
Z = rv.pdf(pos)
fig, ax = plt.subplots(figsize=(10, 8), subplot_kw={'projection': '3d'})
surf = ax.plot_surface(
X, Y, Z,
cmap='viridis',
linewidth=0,
antialiased=True
)
ax.view_init(elev=25, azim=-50)
ax.set_xlabel('X', fontsize=12)
ax.set_ylabel('Y', fontsize=12)
ax.set_zlabel('Density', fontsize=12)
ax.set_title('Bivariate Normal Distribution (ρ = 0.6)', fontsize=14, fontweight='bold')
fig.colorbar(surf, shrink=0.6, aspect=15, label='Probability Density')
plt.tight_layout()
plt.show()
3. Comparison Dashboard¶
Z1 = X**2 + Y**2
Z2 = X**2 - Y**2
Z3 = np.sin(X) * np.cos(Y)
Z4 = np.exp(-(X**2 + Y**2))
surfaces = [(Z1, 'Paraboloid'), (Z2, 'Saddle'), (Z3, 'Wave'), (Z4, 'Gaussian')]
fig, axes = plt.subplots(2, 2, figsize=(14, 12), subplot_kw={'projection': '3d'})
for ax, (Z, title) in zip(axes.flat, surfaces):
ax.plot_surface(X, Y, Z, cmap='coolwarm', linewidth=0)
ax.view_init(elev=30, azim=-45)
ax.set_title(title, fontsize=12)
ax.set_xlabel('X')
ax.set_ylabel('Y')
plt.tight_layout()
plt.show()