Skip to content

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()
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()