Matplotlib画曲线和曲面,3D绘图

  |  

摘要: Matplotlib 画 3D 图的例子、曲线和曲面

【对数据分析、人工智能、金融科技、风控服务感兴趣的同学,欢迎关注我哈,阅读更多原创文章】
我的网站:潮汐朝夕的生活实验室
我的公众号:潮汐朝夕
我的知乎:潮汐朝夕
我的github:FennelDumplings
我的leetcode:FennelDumplings


本文我们总结一下在 Matplotlib 中画平面曲线、空间曲线、空间曲面的方法。

在 Matplotlib 中调用 add_subplot 创建 axes 时,设置 projection="3d" 之后可以进行 3D 绘图。

平面曲线

参数方程

画出以下参数方程表示的平面曲线:

画图方法:plot

这个是折线图,不连续的曲线不适用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import matplotlib.pyplot as plt
import numpy as np

def x(theta):
return 2 * (theta - np.sin(theta))

def y(theta):
return 2 * (1 - np.cos(theta))

Theta = np.linspace(-10, 10, 200)
X = x(Theta)
Y = y(Theta)

fig=plt.figure()
axis = plt.axes()
axis.plot(X, Y)
axis.set_xlabel('x-axis')
axis.set_ylabel('y-axis')
plt.axis('equal')
plt.show()

画图方法:scatter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import matplotlib.pyplot as plt
import numpy as np

def x(theta):
return 2 * (theta - np.sin(theta))

def y(theta):
return 2 * (1 - np.cos(theta))

Theta = np.linspace(-10, 10, 200)
X = x(Theta)
Y = y(Theta)

fig=plt.figure()
axis = plt.axes()
axis.scatter(X, Y)
axis.set_xlabel('x-axis')
axis.set_ylabel('y-axis')
plt.axis('equal')
plt.show()

隐函数

画出以下隐函数表示的平面曲线:

画图方法:contour

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import matplotlib.pyplot as plt
import numpy as np

def F(x, y):
return (x**2 + y**2 - 1)**3 - x**2 * y**3

X, Y = np.meshgrid(np.linspace(-2, 2, 500), np.linspace(-2, 2, 500))
Z = F(X, Y)

fig=plt.figure()
axis = plt.axes()
axis.contour(X, Y, Z, levels=0)
axis.set_xlabel('x-axis')
axis.set_ylabel('y-axis')
plt.show()


空间曲线

参数方程

画出以下参数方程表示的空间曲线:

画图方法:plot3D

这个是折线图,不连续的曲线不适用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import matplotlib.pyplot as plt
import numpy as np

def x(t):
return np.sin(t)

def y(t):
return t * t

def z(t):
return t

T = np.linspace(0, 20, 200)
X = x(T)
Y = y(T)
Z = z(T)

fig = plt.figure()
ax3d_1 = fig.add_subplot(1, 1, 1, projection="3d")
ax3d_1.plot3D(X, Y, Z, zdir="z")
ax3d_1.set_xlabel("x")
ax3d_1.set_ylabel("y")
ax3d_1.set_zlabel("z")
plt.show()

画图方法:scatter3D

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import matplotlib.pyplot as plt
import numpy as np

def x(t):
return np.sin(t)

def y(t):
return t * t

def z(t):
return t

T = np.linspace(0, 20, 200)
X = x(T)
Y = y(T)
Z = z(T)

fig = plt.figure()
ax3d_1 = fig.add_subplot(1, 1, 1, projection="3d")
ax3d_1.scatter3D(X, Y, Z, c=Z, cmap="Greens")
ax3d_1.set_xlabel("x")
ax3d_1.set_ylabel("y")
ax3d_1.set_zlabel("z")
plt.show()


空间曲面

参数方程

画出以下参数方程表示的表示的曲面:

画图方法:contour3D

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import matplotlib.pyplot as plt
import numpy as np

def x(u, v):
return u

def y(u, v):
return v

def z(u, v):
return np.sqrt(u * u + v * v)

U = np.linspace(-5, 5, 20)
V = np.linspace(-5, 5, 20)

X = U
Y = V
X, Y = np.meshgrid(X, Y)
Z = np.sqrt(X * X + Y * Y)

fig=plt.figure()
axis = plt.axes(projection='3d')
axis.contour3D(X, Y, Z, 50, cmap='Greens')
axis.set_xlabel('x-axis')
axis.set_ylabel('y-axis')
axis.set_zlabel('z-axis')
plt.show()

画图方法:scatter3D

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import matplotlib.pyplot as plt
import numpy as np

def x(u, v):
return u

def y(u, v):
return v

def z(u, v):
return np.sqrt(u * u + v * v)

U = np.linspace(-5, 5, 20)
V = np.linspace(-5, 5, 20)

X = U
Y = V
X, Y = np.meshgrid(X, Y)
Z = np.sqrt(X * X + Y * Y)

fig=plt.figure()
axis = plt.axes(projection='3d')
axis.scatter3D(X, Y, Z, cmap='Greens')
axis.set_xlabel('x-axis')
axis.set_ylabel('y-axis')
axis.set_zlabel('z-axis')
plt.show()

隐函数

画出以下隐函数表示的空间曲面:

隐函数表示的曲面,在 Matplotlib 中不是很好画,对于具体的隐函数,建议想办法转为参数方程。

二元函数形式

画出以下二元函数表示的曲面:

画图方法:plot_surface/plot_wireframe

以曲面形式显示高度方向的值,可以映射颜色,用颜色显示高度的值。用 plot_surface() 方法绘制,格式如下:

1
plot_surface(X, Y, Z, *args, norm=None, vmin=None, vmax=None, lightsource=None, **kwargs)

另外可以用 plot_wireframe() 方法绘制不带颜色的线架图,与 plot_surface() 用法相同。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import numpy as np
import matplotlib.pyplot as plt

def f(x, y):
return 2 * (1 - x / 4 + x**5 + y**4) * np.exp(-x**2 - y**2)

n = 50
x = np.linspace(-3, 3, n)
y = np.linspace(-3, 3, n)
X, Y = np.meshgrid(x, y)
Z = f(X, Y)

fig = plt.figure()
ax3d_1 = fig.add_subplot(1, 3, 1, projection="3d")
ax3d_1.plot_surface(X, Y, Z, rcount=50, ccount=50, cmap="jet") # 绘制曲面
ax3d_1.view_init(30, 200) # 视角

ax3d_2 = fig.add_subplot(1, 3, 2, projection="3d")
ax3d_2.plot_surface(X, Y, Z, rcount=6, ccount=6, cmap="jet") # 绘制曲面
ax3d_2.view_init(30, 200) # 视角

ax3d_3 = fig.add_subplot(1, 3, 3, projection="3d")
ax3d_3.plot_wireframe(X, Y, Z, rcount=6, ccount=6, cmap="jet") # 绘制曲面
ax3d_3.view_init(30, 200) # 视角

plt.show()

$z = 2(1 - \frac{x}{4} + x^{5} + y^{4})e^{-x^{2}-y^{2}}$ 的曲面图像


Share