使用 Seaborn 和 Matplotlib 建立 3D 繪圖
在這個解釋中,我們看看什麼是 3D 繪圖,並且我們還學習瞭如何在 seaborn 和 matplotlib 的幫助下建立幾個不同的 3D 繪圖。
使用 Seaborn 和 Matplotlib 建立 3D 繪圖
讓我們從匯入 Matplotlib、NumPy 和 Seaborn 開始。
import seaborn as seaborn
import matplotlib.pyplot as plot
import numpy as np
現在我們使用 NumPy 的隨機模組來建立一些 x
、y
和 z
資料,我們總共有 50 個點。
mean = 3
number = 50
x1 = np.random.normal(mean, 1, size=number)
y1 = np.random.normal(mean, 1, size=number)
z1 = np.random.normal(mean, 1, size=number)
我們可以使用 Matplotlib 製作幾種不同的 3D 圖。每當我們想用 Matplotlib 進行 3D 繪圖時,我們首先需要使用 axes()
函式建立一組軸。
我們將使用 projection
關鍵字並將 3D 值作為字串傳遞。這將告訴 Matplotlib 我們將在三個維度上建立一些東西。
plot.figure(figsize=(6, 5))
axes = plot.axes(projection="3d")
如果我們檢查 axes
的型別,我們將看到這些是 3D 子圖軸。
print(type(axes))
輸出:
<class 'matplotlib.axes._subplots.Axes3DSubplot'>
我們需要呼叫 scatter3D()
函式並傳遞我們的 x
、y
和 z
資料點。這並不容易表示哪一個是 x
軸、y
軸等等,所以讓我們為 3 個維度設定標籤。
import seaborn as seaborn
import matplotlib.pyplot as plot
import numpy as np
seaborn.set_style("darkgrid")
mean = 3
number = 50
x1 = np.random.normal(mean, 1, size=number)
y1 = np.random.normal(mean, 1, size=number)
z1 = np.random.normal(mean, 1, size=number)
plot.figure(figsize=(6, 5))
axes = plot.axes(projection="3d")
print(type(axes))
axes.scatter3D(x1, y1, z1)
axes.set_xlabel("x")
axes.set_ylabel("y")
axes.set_zlabel("z")
plot.show()
輸出:
如果我們想增加散點的大小,我們可以引用這個 s
引數並將其增加到 100。
import seaborn as seaborn
import matplotlib.pyplot as plot
import numpy as np
seaborn.set_style("darkgrid")
mean = 3
number = 50
x1 = np.random.normal(mean, 1, size=number)
y1 = np.random.normal(mean, 1, size=number)
z1 = np.random.normal(mean, 1, size=number)
plot.figure(figsize=(6, 5))
axes = plot.axes(projection="3d")
print(type(axes))
axes.scatter3D(x1, y1, z1, s=100)
axes.set_xlabel("x")
axes.set_ylabel("y")
axes.set_zlabel("z")
plot.show()
輸出:
我們可以使用 view_init()
方法旋轉這個三維圖形。這個方法接受兩個引數,第一個是我們的仰角,第二個是我們的方位角。
我們將以度為單位更改仰角,而不是弧度。我們可能還想在地平線上旋轉這個圖形,這就是我們的方位角。
import seaborn as seaborn
import matplotlib.pyplot as plot
import numpy as np
seaborn.set_style("darkgrid")
mean = 3
number = 50
x1 = np.random.normal(mean, 1, size=number)
y1 = np.random.normal(mean, 1, size=number)
z1 = np.random.normal(mean, 1, size=number)
plot.figure(figsize=(6, 5))
axes = plot.axes(projection="3d")
print(type(axes))
axes.scatter3D(x1, y1, z1)
axes.set_xlabel("x")
axes.set_ylabel("y")
axes.set_zlabel("z")
axes.view_init(45, 215)
plot.show()
輸出:
Matplotlib 提供了建立線圖的選項,我們將建立一些新資料來炫耀。我們需要建立 z
,一個從 0 到 10 的線性空間,然後根據 z
軸的餘弦和正弦建立 x
和 y
。
與 scatter3D()
一樣,我們呼叫 plot3D()
,這將給我們一個線圖。
import seaborn as sb
import matplotlib.pyplot as plot
import numpy as np
sb.set_style("whitegrid")
OMEGA = 2
Z1 = np.linspace(0, 10, 100)
X1 = np.cos(OMEGA * Z1)
Y1 = np.sin(OMEGA * Z1)
plot.figure(figsize=(6, 5))
axes = plot.axes(projection="3d")
axes.plot3D(X1, Y1, Z1)
# keeps padding between figure elements
plot.tight_layout()
plot.show()
現在我們有了一個在三維空間中表示的漂亮的螺旋形圖。
我們可以為二維繪圖使用相同的關鍵字來設定這條線的樣式。假設我們可以改變我們的線寬,讓這個螺旋線變暗一點。
名為 OMEGA
的引數基本上控制了我們希望在繪圖中看到多少個螺旋。
import seaborn as sb
import matplotlib.pyplot as plot
import numpy as np
sb.set_style("whitegrid")
OMEGA = 4
Z1 = np.linspace(0, 10, 100)
X1 = np.cos(OMEGA * Z1)
Y1 = np.sin(OMEGA * Z1)
plot.figure(figsize=(6, 5))
axes = plot.axes(projection="3d")
axes.plot3D(X1, Y1, Z1, lw=3)
# keeps padding between figure elements
plot.tight_layout()
plot.show()
現在我們可以在圖中看到更厚的螺旋。
我們還可以使用 Matplotlib 建立 3 維曲面和線框。
讓我們建立一個 FUNC_Z()
函式。它將採用 x
和 y
值並將我們將繪製到表面的函式返回。
def FUNC_Z(x, y):
return 50 - (x ** 2 + y ** 2)
我們使用 linspace 在 -5 和 5 之間為 x
和 y
建立 50 個間隔。我們需要建立一個網格而不是隻有 x 和 y 值。
我們可以使用 meshgrid()
函式建立它。我們需要向它傳遞 x
和 y
值,以便它重複它們。
X1, Y1 = np.meshgrid(X_VAL, Y_VAL)
完整程式碼:
import seaborn as sb
import matplotlib.pyplot as plot
import numpy as np
def FUNC_Z(x, y):
return 50 - (x ** 2 + y ** 2)
sb.set_style("whitegrid")
N = 50
X_VAL = np.linspace(-5, 5, N)
Y_VAL = np.linspace(-5, 5, N)
X1, Y1 = np.meshgrid(X_VAL, Y_VAL)
Z1 = FUNC_Z(X1, Y1)
axes = plot.axes(projection="3d")
axes.plot_surface(X1, Y1, Z1)
plot.show()
輸出:
讓我們使用 plot_wireframe()
函式建立一個線框圖。這段程式碼看起來與表面非常相似。
import seaborn as sb
import matplotlib.pyplot as plot
import numpy as np
def FUNC_Z(x, y):
return 50 - (x ** 2 + y ** 2)
sb.set_style("whitegrid")
N = 50
X_VAL = np.linspace(-5, 5, N)
Y_VAL = np.linspace(-5, 5, N)
X1, Y1 = np.meshgrid(X_VAL, Y_VAL)
Z1 = FUNC_Z(X1, Y1)
axes = plot.axes(projection="3d")
axes.plot_wireframe(X1, Y1, Z1)
plot.show()
現在我們有一個線框而不是一個表面,它沒有填充中間部分。
如果我們改變網格上的點數,我們可以改變這個線框的美感。
import seaborn as sb
import matplotlib.pyplot as plot
import numpy as np
def FUNC_Z(x, y):
return 50 - (x ** 2 + y ** 2)
sb.set_style("whitegrid")
N = 10
X_VAL = np.linspace(-5, 5, N)
Y_VAL = np.linspace(-5, 5, N)
X1, Y1 = np.meshgrid(X_VAL, Y_VAL)
Z1 = FUNC_Z(X1, Y1)
axes = plot.axes(projection="3d")
axes.plot_wireframe(X1, Y1, Z1)
plot.show()
由於我們改變了網格的大小,它將創造出具有更多空間的不同美學。我們還可以選擇使用滑鼠,單擊該圖形,然後拖動它。
Hello! I am Salman Bin Mehmood(Baum), a software developer and I help organizations, address complex problems. My expertise lies within back-end, data science and machine learning. I am a lifelong learner, currently working on metaverse, and enrolled in a course building an AI application with python. I love solving problems and developing bug-free software for people. I write content related to python and hot Technologies.
LinkedIn