Matplotlib 3D绘图全面指南:从基础到高级技巧
参考:Introduction to 3D Plotting with Matplotlib
Matplotlib是Python中最流行的数据可视化库之一,不仅支持2D绘图,还提供了强大的3D绘图功能。本文将全面介绍Matplotlib的3D绘图功能,从基础概念到高级技巧,帮助您掌握3D数据可视化的精髓。
1. Matplotlib 3D绘图基础
在开始3D绘图之前,我们需要了解Matplotlib中的3D绘图基础。首先,我们需要导入必要的模块并创建一个3D图形对象。
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.set_title('How2matplotlib.com 3D Plot')
plt.show()
Output:
这段代码创建了一个空白的3D图形。我们导入了Axes3D
模块,它是Matplotlib中处理3D绘图的核心。通过设置projection='3d'
,我们告诉Matplotlib我们要创建一个3D图形。
2. 绘制3D散点图
散点图是最基本的3D图形之一,它可以帮助我们直观地观察数据在三维空间中的分布。
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
# 生成随机数据
n = 100
x = np.random.rand(n)
y = np.random.rand(n)
z = np.random.rand(n)
ax.scatter(x, y, z, c='r', marker='o')
ax.set_xlabel('X axis')
ax.set_ylabel('Y axis')
ax.set_zlabel('Z axis')
ax.set_title('How2matplotlib.com 3D Scatter Plot')
plt.show()
Output:
在这个例子中,我们生成了100个随机的三维数据点,并使用ax.scatter()
函数将它们绘制在3D空间中。我们还设置了坐标轴标签和图形标题。
3. 绘制3D曲面图
3D曲面图可以用来表示三维函数或者三维数据集。下面是一个简单的例子:
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
# 生成数据
X = np.arange(-5, 5, 0.25)
Y = np.arange(-5, 5, 0.25)
X, Y = np.meshgrid(X, Y)
R = np.sqrt(X**2 + Y**2)
Z = np.sin(R)
# 绘制曲面
surf = ax.plot_surface(X, Y, Z, cmap='viridis')
ax.set_xlabel('X axis')
ax.set_ylabel('Y axis')
ax.set_zlabel('Z axis')
ax.set_title('How2matplotlib.com 3D Surface Plot')
# 添加颜色条
fig.colorbar(surf, shrink=0.5, aspect=5)
plt.show()
Output:
这个例子展示了如何绘制一个3D曲面图。我们首先生成了X和Y的网格数据,然后计算Z值。ax.plot_surface()
函数用于绘制曲面,我们还添加了一个颜色条来显示Z值的范围。
4. 绘制3D线图
3D线图可以用来表示三维空间中的路径或轨迹。
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
# 生成数据
t = np.linspace(0, 10, 100)
x = np.sin(t)
y = np.cos(t)
z = t
ax.plot(x, y, z, label='How2matplotlib.com 3D curve')
ax.set_xlabel('X axis')
ax.set_ylabel('Y axis')
ax.set_zlabel('Z axis')
ax.set_title('How2matplotlib.com 3D Line Plot')
ax.legend()
plt.show()
Output:
这个例子展示了如何绘制一个3D螺旋线。我们使用参数方程生成了x、y和z坐标,然后使用ax.plot()
函数绘制3D线图。
5. 3D柱状图
3D柱状图可以用来比较多个类别的数据在三个维度上的分布。
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
# 生成数据
x = np.arange(5)
y = np.arange(5)
z = np.random.randint(10, size=(5, 5))
# 设置柱子的位置和大小
dx = dy = 0.8
dz = z
# 绘制3D柱状图
for i in range(5):
for j in range(5):
ax.bar3d(x[i], y[j], 0, dx, dy, dz[i, j])
ax.set_xlabel('X axis')
ax.set_ylabel('Y axis')
ax.set_zlabel('Z axis')
ax.set_title('How2matplotlib.com 3D Bar Plot')
plt.show()
Output:
这个例子展示了如何创建一个3D柱状图。我们使用ax.bar3d()
函数来绘制每个柱子,指定了柱子的位置、宽度、深度和高度。
6. 3D等高线图
3D等高线图可以用来表示三维曲面的轮廓。
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
# 生成数据
X = np.arange(-5, 5, 0.25)
Y = np.arange(-5, 5, 0.25)
X, Y = np.meshgrid(X, Y)
R = np.sqrt(X**2 + Y**2)
Z = np.sin(R)
# 绘制等高线
ax.contour(X, Y, Z, zdir='z', offset=-2, cmap='viridis')
ax.set_xlabel('X axis')
ax.set_ylabel('Y axis')
ax.set_zlabel('Z axis')
ax.set_title('How2matplotlib.com 3D Contour Plot')
plt.show()
Output:
这个例子展示了如何在3D图形中添加等高线。我们使用ax.contour()
函数来绘制等高线,zdir
参数指定了等高线的投影方向,offset
参数指定了等高线在z轴上的位置。
7. 3D网格图
3D网格图可以用来表示三维曲面的骨架结构。
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
# 生成数据
X = np.arange(-5, 5, 0.5)
Y = np.arange(-5, 5, 0.5)
X, Y = np.meshgrid(X, Y)
R = np.sqrt(X**2 + Y**2)
Z = np.sin(R)
# 绘制网格
ax.plot_wireframe(X, Y, Z, rstride=1, cstride=1)
ax.set_xlabel('X axis')
ax.set_ylabel('Y axis')
ax.set_zlabel('Z axis')
ax.set_title('How2matplotlib.com 3D Wireframe Plot')
plt.show()
Output:
这个例子展示了如何创建一个3D网格图。我们使用ax.plot_wireframe()
函数来绘制网格,rstride
和cstride
参数控制网格的密度。
8. 3D填充图
3D填充图可以用来表示三维空间中的封闭区域。
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
# 生成数据
theta = np.linspace(0, 2*np.pi, 100)
z = np.linspace(0, 2, 100)
r = z**2 + 1
x = r * np.sin(theta)
y = r * np.cos(theta)
# 绘制3D填充图
ax.plot(x, y, z, label='How2matplotlib.com 3D parametric curve')
ax.legend()
ax.set_xlabel('X axis')
ax.set_ylabel('Y axis')
ax.set_zlabel('Z axis')
ax.set_title('How2matplotlib.com 3D Filled Plot')
plt.show()
Output:
这个例子展示了如何创建一个3D填充图。我们使用参数方程生成了一个螺旋形的曲线,然后使用ax.plot()
函数绘制这个曲线。
9. 3D散点图与颜色映射
我们可以使用颜色映射来为3D散点图添加额外的维度信息。
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
# 生成数据
n = 100
x = np.random.rand(n)
y = np.random.rand(n)
z = np.random.rand(n)
c = np.random.rand(n)
# 绘制散点图
scatter = ax.scatter(x, y, z, c=c, cmap='viridis')
ax.set_xlabel('X axis')
ax.set_ylabel('Y axis')
ax.set_zlabel('Z axis')
ax.set_title('How2matplotlib.com 3D Scatter Plot with Color Mapping')
# 添加颜色条
plt.colorbar(scatter)
plt.show()
Output:
在这个例子中,我们为每个点添加了一个额外的颜色值,并使用cmap
参数指定了颜色映射。我们还添加了一个颜色条来显示颜色值的范围。
10. 3D箭头图
3D箭头图可以用来表示三维空间中的向量场。
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
# 生成数据
x, y, z = np.meshgrid(np.arange(-0.8, 1, 0.2),
np.arange(-0.8, 1, 0.2),
np.arange(-0.8, 1, 0.8))
u = np.sin(np.pi * x) * np.cos(np.pi * y) * np.cos(np.pi * z)
v = -np.cos(np.pi * x) * np.sin(np.pi * y) * np.cos(np.pi * z)
w = (np.sqrt(2.0 / 3.0) * np.cos(np.pi * x) * np.cos(np.pi * y) *
np.sin(np.pi * z))
# 绘制箭头
ax.quiver(x, y, z, u, v, w, length=0.1, normalize=True)
ax.set_xlabel('X axis')
ax.set_ylabel('Y axis')
ax.set_zlabel('Z axis')
ax.set_title('How2matplotlib.com 3D Arrow Plot')
plt.show()
Output:
这个例子展示了如何创建一个3D箭头图。我们使用ax.quiver()
函数来绘制箭头,指定了箭头的起点坐标(x, y, z)和方向向量(u, v, w)。
11. 3D等值面图
3D等值面图可以用来表示三维标量场中的等值面。
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
# 生成数据
x, y, z = np.meshgrid(np.arange(-1, 1, 0.1),
np.arange(-1, 1, 0.1),
np.arange(-1, 1, 0.1))
values = x**2 + y**2 + z**2
# 绘制等值面
ax.contourf(x[:,:,0], y[:,:,0], values[:,:,0], zdir='z', offset=-1, cmap='viridis')
ax.contourf(x[0,:,:], values[0,:,:], z[0,:,:], zdir='y', offset=1, cmap='viridis')
ax.contourf(values[:,0,:], y[:,0,:], z[:,0,:], zdir='x', offset=-1, cmap='viridis')
ax.set_xlabel('X axis')
ax.set_ylabel('Y axis')
ax.set_zlabel('Z axis')
ax.set_title('How2matplotlib.com 3D Isosurface Plot')
plt.show()
Output:
这个例子展示了如何创建一个3D等值面图。我们使用ax.contourf()
函数在三个正交平面上绘制等值线,从而创建了一个3D等值面的效果。
12. 3D多子图
有时我们需要在一个图形中展示多个3D图。Matplotlib允许我们创建包含多个3D子图的图形。
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as npfig = plt.figure(figsize=(12, 5))
# 第一个子图:3D散点图
ax1 = fig.add_subplot(121, projection='3d')
n = 100
x = np.random.rand(n)
y = np.random.rand(n)
z = np.random.rand(n)
ax1.scatter(x, y, z)
ax1.set_title('How2matplotlib.com 3D Scatter')
# 第二个子图:3D曲面图
ax2 = fig.add_subplot(122, projection='3d')
X = np.arange(-5, 5, 0.25)
Y = np.arange(-5, 5, 0.25)
X, Y = np.meshgrid(X, Y)
R = np.sqrt(X**2 + Y**2)
Z = np.sin(R)
surf = ax2.plot_surface(X, Y, Z, cmap='viridis')
ax2.set_title('How2matplotlib.com 3D Surface')
plt.tight_layout()
plt.show()
这个例子展示了如何在一个图形中创建两个3D子图。我们使用fig.add_subplot()
函数创建了两个子图,一个是3D散点图,另一个是3D曲面图。figsize
参数用于设置整个图形的大小,tight_layout()
函数用于自动调整子图之间的间距。
13. 3D动画
Matplotlib还支持创建3D动画,这可以用来展示随时间变化的3D数据。
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
from matplotlib.animation import FuncAnimation
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
# 初始化数据
t = np.linspace(0, 20, 100)
x = np.cos(t)
y = np.sin(t)
z = t
# 初始化线条
line, = ax.plot(x, y, z)
# 更新函数
def update(frame):
ax.view_init(elev=10., azim=frame)
ax.set_title(f'How2matplotlib.com 3D Animation (Frame {frame})')
return line,
# 创建动画
anim = FuncAnimation(fig, update, frames=np.linspace(0, 360, 100), interval=50, blit=True)
ax.set_xlabel('X axis')
ax.set_ylabel('Y axis')
ax.set_zlabel('Z axis')
plt.show()
Output:
这个例子展示了如何创建一个3D动画。我们使用FuncAnimation
类来创建动画,update
函数定义了每一帧的更新内容。在这个例子中,我们通过改变视角来创建旋转的效果。
14. 3D文本
在3D图形中添加文本可以帮助我们标注重要的点或区域。
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
# 生成一些随机点
n = 10
xs = np.random.rand(n)
ys = np.random.rand(n)
zs = np.random.rand(n)
# 绘制散点图
ax.scatter(xs, ys, zs)
# 为每个点添加文本标签
for x, y, z in zip(xs, ys, zs):
label = f'({x:.2f}, {y:.2f}, {z:.2f})'
ax.text(x, y, z, label, fontsize=9)
ax.set_xlabel('X axis')
ax.set_ylabel('Y axis')
ax.set_zlabel('Z axis')
ax.set_title('How2matplotlib.com 3D Text')
plt.show()
Output:
这个例子展示了如何在3D图形中添加文本。我们使用ax.text()
函数为每个散点添加了坐标标签。
15. 3D极坐标图
Matplotlib也支持在3D空间中绘制极坐标图。
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
# 生成数据
theta = np.linspace(0, 2*np.pi, 100)
r = 2 + np.sin(7*theta)
z = np.linspace(0, 2, 100)
# 转换为笛卡尔坐标
x = r * np.cos(theta)
y = r * np.sin(theta)
# 绘制3D极坐标图
ax.plot(x, y, z)
ax.set_xlabel('X axis')
ax.set_ylabel('Y axis')
ax.set_zlabel('Z axis')
ax.set_title('How2matplotlib.com 3D Polar Plot')
plt.show()
Output:
这个例子展示了如何创建一个3D极坐标图。我们首先在极坐标系中生成数据,然后将其转换为笛卡尔坐标系,最后使用ax.plot()
函数绘制3D曲线。
16. 3D直方图
3D直方图可以用来可视化三维数据的分布。
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
# 生成数据
x = np.random.normal(0, 1, 1000)
y = np.random.normal(0, 1, 1000)
# 计算直方图
hist, xedges, yedges = np.histogram2d(x, y, bins=20)
# 准备网格数据
xpos, ypos = np.meshgrid(xedges[:-1] + 0.25, yedges[:-1] + 0.25, indexing="ij")
xpos = xpos.ravel()
ypos = ypos.ravel()
zpos = 0
# 准备柱子数据
dx = dy = 0.5 * np.ones_like(zpos)
dz = hist.ravel()
# 绘制3D直方图
ax.bar3d(xpos, ypos, zpos, dx, dy, dz, zsort='average')
ax.set_xlabel('X axis')
ax.set_ylabel('Y axis')
ax.set_zlabel('Frequency')
ax.set_title('How2matplotlib.com 3D Histogram')
plt.show()
Output:
这个例子展示了如何创建一个3D直方图。我们首先使用np.histogram2d()
函数计算2D直方图数据,然后使用ax.bar3d()
函数绘制3D柱状图。
17. 3D等高线填充图
3D等高线填充图可以用来表示三维曲面的轮廓和高度。
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
# 生成数据
X = np.arange(-5, 5, 0.25)
Y = np.arange(-5, 5, 0.25)
X, Y = np.meshgrid(X, Y)
R = np.sqrt(X**2 + Y**2)
Z = np.sin(R)
# 绘制等高线填充图
cset = ax.contourf(X, Y, Z, zdir='z', offset=-2, cmap='viridis')
# 绘制曲面
ax.plot_surface(X, Y, Z, rstride=1, cstride=1, alpha=0.3)
ax.set_xlabel('X axis')
ax.set_ylabel('Y axis')
ax.set_zlabel('Z axis')
ax.set_title('How2matplotlib.com 3D Filled Contour Plot')
plt.colorbar(cset)
plt.show()
Output:
这个例子展示了如何创建一个3D等高线填充图。我们使用ax.contourf()
函数绘制填充的等高线,然后使用ax.plot_surface()
函数绘制半透明的曲面。
18. 3D散点图与投影
我们可以在3D散点图中添加投影,以更好地展示数据在各个平面上的分布。
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
# 生成数据
n = 100
x = np.random.rand(n)
y = np.random.rand(n)
z = np.random.rand(n)
# 绘制散点图
ax.scatter(x, y, z, c='r', marker='o')
# 添加投影
ax.scatter(x, y, zs=0, zdir='z', c='b', marker='^')
ax.scatter(x, zs=0, ys=z, zdir='y', c='g', marker='s')
ax.scatter(zs=0, xs=y, ys=z, zdir='x', c='k', marker='d')
ax.set_xlabel('X axis')
ax.set_ylabel('Y axis')
ax.set_zlabel('Z axis')
ax.set_title('How2matplotlib.com 3D Scatter Plot with Projections')
plt.show()
Output:
这个例子展示了如何在3D散点图中添加投影。我们使用ax.scatter()
函数绘制主散点图和三个平面上的投影,通过设置不同的zdir
参数来指定投影的方向。
19. 3D矢量场
3D矢量场可以用来可视化三维空间中的向量数据。
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
# 生成数据
x, y, z = np.meshgrid(np.arange(-0.8, 1, 0.2),
np.arange(-0.8, 1, 0.2),
np.arange(-0.8, 1, 0.2))
u = np.sin(np.pi * x) * np.cos(np.pi * y) * np.cos(np.pi * z)
v = -np.cos(np.pi * x) * np.sin(np.pi * y) * np.cos(np.pi * z)
w = (np.sqrt(2.0 / 3.0) * np.cos(np.pi * x) * np.cos(np.pi * y) *
np.sin(np.pi * z))
# 绘制矢量场
ax.quiver(x, y, z, u, v, w, length=0.1, normalize=True)
ax.set_xlabel('X axis')
ax.set_ylabel('Y axis')
ax.set_zlabel('Z axis')
ax.set_title('How2matplotlib.com 3D Vector Field')
plt.show()
Output:
这个例子展示了如何创建一个3D矢量场。我们使用ax.quiver()
函数来绘制箭头,表示每个点的向量方向和大小。
20. 3D等值面与切片
3D等值面与切片可以帮助我们理解三维数据的内部结构。
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
# 生成数据
x, y, z = np.meshgrid(np.arange(-1, 1, 0.1),
np.arange(-1, 1, 0.1),
np.arange(-1, 1, 0.1))
values = x**2 + y**2 + z**2
# 绘制等值面
ax.contour(x[:,:,0], y[:,:,0], values[:,:,0], zdir='z', offset=-1, cmap='viridis')
ax.contour(x[0,:,:], values[0,:,:], z[0,:,:], zdir='y', offset=1, cmap='viridis')
ax.contour(values[:,0,:], y[:,0,:], z[:,0,:], zdir='x', offset=-1, cmap='viridis')
# 绘制切片
ax.contourf(x[:,:,10], y[:,:,10], values[:,:,10], zdir='z', offset=0, cmap='viridis')
ax.set_xlabel('X axis')
ax.set_ylabel('Y axis')
ax.set_zlabel('Z axis')
ax.set_title('How2matplotlib.com 3D Isosurface and Slice')
plt.show()
Output:
这个例子展示了如何创建3D等值面和切片图。我们使用ax.contour()
函数绘制等值面,使用ax.contourf()
函数绘制切片。
总结:本文全面介绍了Matplotlib的3D绘图功能,从基础的散点图、线图、曲面图,到高级的等值面图、矢量场图等。我们还探讨了如何添加颜色映射、创建动画、添加文本标注等技巧。通过这些示例,读者应该能够掌握使用Matplotlib创建各种类型的3D图形的方法,从而更好地可视化和分析三维数据。希望这篇文章能够帮助你在数据可视化的道路上更进一步!