【matplotlib基礎】--3D圖形

wang_yb發表於2023-09-23

matplotlib1.0版本之前其實是不支援3D圖形繪製的。

後來的版本中,matplotlib加入了3D圖形的支援,不僅僅是為了使資料的展示更加生動和有趣。
更重要的是,由於多了一個維度,擴充套件了其展示資料分佈和關係的能力,可以一次從三個維度來比較資料。

下面介紹在matplotlib中繪製各類3D圖形的方法。

1. 點和線

點和線類的圖形轉成3D比較簡單,只要加個維度即可。
比如:

import numpy as np

import matplotlib
import matplotlib.pyplot as plt

n = 10
xs = np.linspace(0, 100, n)
ys = np.linspace(100, 200, n)

fig, ax = plt.subplots()
ax.scatter(xs, ys, color="r")
ax.plot(xs, ys)

plt.show()

image.png

增加一個維度,改成3D圖形:

n = 10
xs = np.linspace(0, 100, n)
ys = np.linspace(100, 200, n)
zs = xs + ys  #增加一個維度,值為x+y的和

fig, ax = plt.subplots(subplot_kw={"projection": "3d"})
ax.scatter(xs, ys, zs, color='r')
ax.plot(xs, ys, zs)

plt.show()

image.png
注意,獲取子圖的時候,subplot_kw={"projection": "3d"} 這個引數很重要,它會把座標系對映成3維的。

2. 面

繪製面或者曲面的時候稍微複雜一些,不像點和麵只要簡單的增加一個維度就可以了。

比如,對於曲面函式:\(z = x*y^3 - y*x^3\)
繪製時,不能像如下這樣:

xs = np.arange(-10, 10, 0.5)
ys = np.arange(-10, 10, 0.5)
zs = xs * (ys**3) - ys * (xs**3)

這樣得到的xs, ys, zs只是3維中的一個個點的(x, y, z)座標,無法繪製曲面。
只能像上一節那樣繪製3維中的或者

若要繪製曲面,需要用到numpy提供的meshgrid函式先生成網格。

xs = np.arange(-10, 10, 0.5)
ys = np.arange(-10, 10, 0.5)
xs, ys = np.meshgrid(xs, ys)  #生成網格座標

zs = xs * (ys**3) - ys * (xs**3)  #計算網格中每個點的Z軸座標

這樣,把座標傳入plot_surface函式,就可以繪製最後的3D曲面了。

fig, ax = plt.subplots(subplot_kw={"projection": "3d"})
ax.plot_surface(xs, ys, zs)

plt.show()

image.png

只顯示網格的話,可以用 plot_wireframe 函式。

ax.plot_wireframe(xs, ys, zs)

image.png

從這個示例可以看出,3D曲面其實是一個個網格拼接而成的,
並沒有想象中的平滑,它的平滑程度取決於網格的大小和密度。

3. 立方體

matplotlib中提供了一個繪製立方體的函式voxels,透過這個函式可以很方便的繪製各種立方體形狀。

我用voxels繪製了一個簡易的金字塔結構:

x, y, z = np.indices((10, 10, 8))

cube1 = (x < 9) & (y < 9) & (z == 1)
cube2 = (x > 0) & (x < 8) & (y > 0) & (y < 8) & (z == 2)
cube3 = (x > 1) & (x < 7) & (y > 1) & (y < 7) & (z == 3)
cube4 = (x > 2) & (x < 6) & (y > 2) & (y < 6) & (z == 4)
cube5 = (x > 3) & (x < 5) & (y > 3) & (y < 5) & (z == 5)

cube = cube1 | cube2 | cube3 | cube4 | cube5

fig, ax = plt.subplots(subplot_kw={"projection": "3d"})
fig.set_size_inches(8, 6)
ax.voxels(cube, color="goldenrod", edgecolor="g")

plt.show()

image.png

4. 總結

看了matplotlib的3D繪圖功能,尤其是曲面圖繪製方面,
我覺得它的3D功能不僅僅是給分析圖表擴充了一個維度這麼簡單,而是讓它在數學上的表現能力也極大提高了。

配合numpy中的數學函式,3D繪圖能夠展示很多複雜的幾何曲面,讓matplotlib的使用範圍大大擴充。

相關文章