pin_drop当前位置:知识文库 ❯ 图文
Matplotlib 3D绘图完全指南 - 3D散点图、曲面图、柱状图
一、3D绘图概述
matplotlib的mplot3d工具包支持3D图形绘制,包括3D散点图、3D线图、3D曲面图、3D柱状图等。通过mpl_toolkits.mplot3d导入3D功能,创建Axes3D对象即可在三维空间中绘制图形。
3D绘图适合展示三维数据的关系和分布,如空间点云、二元函数曲面、多维数据降维结果等。虽然matplotlib的3D渲染能力不如专业3D库,但对于大多数科学计算和数据可视化场景已经足够。
二、创建3D坐标系
创建3D坐标系是3D绘图的第一步,需要设置projection='3d'参数:
代码示例
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
# 或者使用快捷方式(matplotlib 3.2+)
ax = fig.add_subplot(projection='3d')三、3D散点图与线图
3D散点图展示空间分布
3D散点图适合展示空间点的分布关系,可以通过颜色编码额外维度的信息:
代码示例
import matplotlib.pyplot as plt
import numpy as np
np.random.seed(42)
fig = plt.figure(figsize=(12, 5))
# 3D散点图
ax1 = fig.add_subplot(121, projection='3d')
n = 100
x = np.random.randn(n)
y = np.random.randn(n)
z = np.random.randn(n)
colors = np.sqrt(x**2 + y**2 + z**2)
ax1.scatter(x, y, z, c=colors, cmap='viridis', s=50, alpha=0.7)
ax1.set_title('3D Scatter Plot')
ax1.set_xlabel('X')
ax1.set_ylabel('Y')
ax1.set_zlabel('Z')
# 3D线图 - 螺旋线
ax2 = fig.add_subplot(122, projection='3d')
t = np.linspace(0, 4 * np.pi, 200)
x2 = np.sin(t)
y2 = np.cos(t)
z2 = t
ax2.plot(x2, y2, z2, 'b-', linewidth=2)
ax2.set_title('3D Line Plot (Helix)')
ax2.set_xlabel('X')
ax2.set_ylabel('Y')
ax2.set_zlabel('Z')
plt.tight_layout()
plt.savefig('3d_scatter_line.png', dpi=100, bbox_inches='tight')
print("3D散点与线图已保存")输出:
代码示例
3D散点与线图已保存四、3D曲面图与线框图
3D曲面图需要先用np.meshgrid()生成网格坐标,然后计算Z值:
代码示例
import matplotlib.pyplot as plt
import numpy as np
fig = plt.figure(figsize=(14, 5))
# 生成网格数据
x = np.linspace(-5, 5, 100)
y = np.linspace(-5, 5, 100)
X, Y = np.meshgrid(x, y)
Z = np.sin(np.sqrt(X**2 + Y**2))
# 曲面图
ax1 = fig.add_subplot(131, projection='3d')
surf = ax1.plot_surface(X, Y, Z, cmap='viridis', alpha=0.9)
ax1.set_title('Surface Plot')
fig.colorbar(surf, ax=ax1, shrink=0.5)
# 线框图
ax2 = fig.add_subplot(132, projection='3d')
ax2.plot_wireframe(X, Y, Z, color='blue', rstride=5, cstride=5, alpha=0.6)
ax2.set_title('Wireframe Plot')
# 等高线+曲面
ax3 = fig.add_subplot(133, projection='3d')
ax3.plot_surface(X, Y, Z, cmap='coolwarm', alpha=0.7)
ax3.contour(X, Y, Z, zdir='z', offset=-1.5, cmap='coolwarm')
ax3.set_zlim(-1.5, 1)
ax3.set_title('Surface + Contour')
plt.tight_layout()
plt.savefig('3d_surface.png', dpi=100, bbox_inches='tight')
print("3D曲面图已保存")输出:
代码示例
3D曲面图已保存小贴士
rstride和cstride控制行和列的采样步长,值越大网格越稀疏。当数据量大时,适当增大这两个值可以显著提升渲染速度。
五、3D柱状图与视角控制
3D柱状图与视角对比
代码示例
import matplotlib.pyplot as plt
import numpy as np
fig = plt.figure(figsize=(14, 5))
# 3D柱状图
ax1 = fig.add_subplot(131, projection='3d')
x_pos = [0, 1, 2, 0, 1, 2]
y_pos = [0, 0, 0, 1, 1, 1]
z_pos = [0, 0, 0, 0, 0, 0]
dx = [0.5, 0.5, 0.5, 0.5, 0.5, 0.5]
dy = [0.5, 0.5, 0.5, 0.5, 0.5, 0.5]
dz = [3, 5, 2, 4, 6, 1]
colors = ['#2196F3', '#4CAF50', '#FF9800', '#9C27B0', '#F44336', '#00BCD4']
ax1.bar3d(x_pos, y_pos, z_pos, dx, dy, dz, color=colors, alpha=0.8)
ax1.set_title('3D Bar Chart')
# 不同视角对比
ax2 = fig.add_subplot(132, projection='3d')
t = np.linspace(0, 4*np.pi, 100)
ax2.plot(np.sin(t), np.cos(t), t, 'r-', linewidth=2)
ax2.view_init(elev=0, azim=0)
ax2.set_title('View: elev=0, azim=0')
ax3 = fig.add_subplot(133, projection='3d')
ax3.plot(np.sin(t), np.cos(t), t, 'r-', linewidth=2)
ax3.view_init(elev=60, azim=45)
ax3.set_title('View: elev=60, azim=45')
plt.tight_layout()
plt.savefig('3d_bar_view.png', dpi=100, bbox_inches='tight')
print("3D柱状图与视角已保存")输出:
代码示例
3D柱状图与视角已保存视角参数详解
六、实际应用场景
-
科学计算:使用3D曲面图展示二元函数的形状,如地形、电势场等
-
地理信息:使用3D柱状图展示不同地区/时间的数值对比
-
机器学习:使用3D散点图可视化高维数据降维后的空间分布
七、注意事项
注意:3D图形必须使用
projection='3d'创建Axes3D对象,否则只能进行2D绘图。
注意:3D曲面图的数据必须使用
np.meshgrid()生成网格坐标,X、Y、Z的维度必须一致。
注意:3D图形渲染较慢,数据量大时应增大
rstride/cstride降低精度以提升性能。
八、常见问题FAQ
3D曲面图的meshgrid有什么用?
meshgrid将一维的x和y向量转换为二维的网格矩阵X和Y,这样每个(X[i,j], Y[i,j])点对应一个Z值,形成曲面所需的网格数据结构。没有meshgrid就无法为曲面的每个点计算正确的Z值。
如何旋转3D图表找到最佳视角?
使用ax.view_init(elev, azim)设置视角。在交互式环境中可以用鼠标拖拽旋转找到最佳角度,然后查看当前角度:print(ax.elev, ax.azim),再将数值写入代码中。
3D绘图和Mayavi/Plotly比有什么优缺点?
matplotlib 3D的优点是简单、无需额外依赖,适合基本的3D可视化。缺点是交互性差、渲染质量有限。如果需要复杂3D交互(旋转、缩放),建议使用Plotly(交互式网页3D)或Mayavi(科学可视化专用)。
如何在3D图中添加图例?
与普通2D图相同,在绘制时设置label参数,然后调用ax.legend()即可。3D散点图可以使用scatter的返回值配合colorbar展示连续颜色映射。
本文涉及AI创作
内容由AI创作,请仔细甄别