Matplotlib 不仅擅长二维绘图,还通过 mplot3d 工具包提供了强大的三维绘图能力。
你可以创建三维散点图、线图、曲面图、线框图等,并从不同视角观察数据。
本章将带你进入三维可视化的世界。
要创建3D坐标轴,需要先导入 mplot3d 模块。通常使用 projection='3d' 参数:
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits import mplot3d # 虽然不总是显式需要,但建议导入
fig = plt.figure()
ax = fig.add_subplot(projection='3d') # 创建3D坐标轴
# 或者使用 subplots
# fig, ax = plt.subplots(subplot_kw={'projection': '3d'})
subplot_kw 的方式创建3D坐标轴。使用 ax.plot3D() 绘制三维曲线:
z = np.linspace(0, 30, 1000)
x = np.sin(z)
y = np.cos(z)
fig, ax = plt.subplots(subplot_kw={'projection': '3d'})
ax.plot3D(x, y, z, 'blue')
ax.set_title('3D螺旋线')
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
plt.show()
使用 ax.scatter3D() 绘制三维散点,可以设置颜色和大小:
np.random.seed(42)
x = np.random.randn(100)
y = np.random.randn(100)
z = np.random.randn(100)
colors = x + y + z
sizes = (x**2 + y**2 + z**2) * 20
fig, ax = plt.subplots(subplot_kw={'projection': '3d'})
sc = ax.scatter3D(x, y, z, c=colors, s=sizes, cmap='viridis', alpha=0.7)
ax.set_title('3D散点图')
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
plt.colorbar(sc, ax=ax, shrink=0.5)
plt.show()
plot_surface 需要二维网格数据,通常使用 np.meshgrid 生成:
x = np.linspace(-5, 5, 50)
y = np.linspace(-5, 5, 50)
X, Y = np.meshgrid(x, y)
Z = np.sin(np.sqrt(X**2 + Y**2))
fig, ax = plt.subplots(subplot_kw={'projection': '3d'})
surf = ax.plot_surface(X, Y, Z, cmap='coolwarm', edgecolor='none')
ax.set_title('3D曲面图')
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
plt.colorbar(surf, ax=ax, shrink=0.5)
plt.show()
线框图只显示线条,不填充颜色,适合观察结构:
fig, ax = plt.subplots(subplot_kw={'projection': '3d'})
ax.plot_wireframe(X, Y, Z, color='black', linewidth=0.5)
ax.set_title('3D线框图')
plt.show()
contour3D 或 contourf3D 可以在3D空间绘制等高线:
fig, ax = plt.subplots(subplot_kw={'projection': '3d'})
ax.contour3D(X, Y, Z, 50, cmap='viridis')
ax.set_title('3D等高线')
plt.show()
contourf3D 填充。可以在底部或侧壁投影等高线,增强可读性:
fig, ax = plt.subplots(subplot_kw={'projection': '3d'})
ax.plot_surface(X, Y, Z, cmap='coolwarm', alpha=0.7)
ax.contour(X, Y, Z, zdir='z', offset=-1.5, cmap='coolwarm') # 投影到底面
ax.contour(X, Y, Z, zdir='x', offset=-6, cmap='coolwarm') # 投影到侧面
ax.set_title('带投影的曲面')
plt.show()
使用 ax.view_init(elev, azim) 调整俯仰角和方位角:
fig, ax = plt.subplots(subplot_kw={'projection': '3d'})
ax.plot_surface(X, Y, Z, cmap='coolwarm')
ax.view_init(elev=30, azim=45) # 俯仰角30°,方位角45°
plt.title('自定义视角')
plt.show()
使用 ax.bar3d 绘制三维条形图:
xpos = np.arange(4)
ypos = np.arange(3)
xpos, ypos = np.meshgrid(xpos, ypos)
xpos = xpos.flatten()
ypos = ypos.flatten()
zpos = np.zeros_like(xpos)
dx = dy = 0.5
dz = np.random.rand(12) * 2
fig, ax = plt.subplots(subplot_kw={'projection': '3d'})
ax.bar3d(xpos, ypos, zpos, dx, dy, dz, color='skyblue')
ax.set_title('3D条形图')
plt.show()
使用 ax.set_xlim(), set_ylim(), set_zlim():
ax.set_xlim(-5, 5)
ax.set_ylim(-5, 5)
ax.set_zlim(-1.5, 1.5)
import matplotlib.pyplot as plt
import numpy as np
# 生成数据
theta = np.linspace(-4 * np.pi, 4 * np.pi, 100)
z = np.linspace(-2, 2, 100)
r = z**2 + 1
x = r * np.sin(theta)
y = r * np.cos(theta)
fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111, projection='3d')
# 绘制螺旋线
ax.plot(x, y, z, 'b-', linewidth=2, label='螺旋线')
# 随机散点
np.random.seed(42)
x_scatter = np.random.randn(50)
y_scatter = np.random.randn(50)
z_scatter = np.random.randn(50) * 2
ax.scatter(x_scatter, y_scatter, z_scatter, c='red', s=30, label='散点')
# 绘制一个透明曲面
X = np.outer(np.linspace(-5, 5, 30), np.ones(30))
Y = X.copy().T
Z = np.sin(X**2 + Y**2) / (X**2 + Y**2 + 1)
ax.plot_surface(X, Y, Z, cmap='viridis', alpha=0.5)
ax.set_xlabel('X轴')
ax.set_ylabel('Y轴')
ax.set_zlabel('Z轴')
ax.set_title('3D综合示例:螺旋线 + 散点 + 曲面')
ax.legend()
# 调整视角
ax.view_init(elev=20, azim=30)
plt.tight_layout()
plt.show()
和2D一样使用 savefig():
plt.savefig('3d_plot.png', dpi=300, bbox_inches='tight')
3D绘图能直观展示多维数据关系,Matplotlib 的 mplot3d 工具包提供了丰富的绘图类型。掌握这些基础后,你可以创建更复杂的三维可视化。下一章将介绍 Matplotlib 的配置系统,让你能够定制全局默认设置。