การแสดง Vector Field (สนามเวกเตอร์) 3 มิติใน Matplotlib ใช้ quiver() บน Axes 3D (mplot3d) โดยระบุตำแหน่ง (X, Y, Z) และองค์ประกอบเวกเตอร์ (U, V, W)
ขั้นตอน
- Import
Axes3Dจากmpl_toolkits.mplot3d - สร้าง Grid 3D ด้วย
np.meshgrid() - คำนวณ Vector Components (U, V, W) ที่แต่ละจุด
- ใช้
ax.quiver(X, Y, Z, U, V, W)วาดลูกศร 3D
ตัวอย่าง: Vector Field รัศมี (Radial Field)
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
plt.rcParams["figure.figsize"] = [12, 10]
plt.rcParams["figure.autolayout"] = True
# สร้าง Grid 3D
n = 6
x = np.linspace(-2, 2, n)
y = np.linspace(-2, 2, n)
z = np.linspace(-2, 2, n)
X, Y, Z = np.meshgrid(x, y, z, indexing='ij')
# Vector Field: Radial Outward (U, V, W = X, Y, Z)
U = X
V = Y
W = Z
# สร้าง Figure 3D
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
# วาด Vector Field
# length=0.3: ความยาวลูกศร, normalize=True: ทำให้ความยาวเท่ากัน
quiver = ax.quiver(X, Y, Z, U, V, W,
length=0.3, normalize=True,
color='royalblue', alpha=0.8,
linewidth=1.5, arrow_length_ratio=0.3)
# ตกแต่ง
ax.set_xlabel('X', fontsize=12, labelpad=10)
ax.set_ylabel('Y', fontsize=12, labelpad=10)
ax.set_zlabel('Z', fontsize=12, labelpad=10)
ax.set_title('3D Radial Vector Field', fontsize=16, pad=20)
# กำหนด Limit
ax.set_xlim(-2.5, 2.5)
ax.set_ylim(-2.5, 2.5)
ax.set_zlim(-2.5, 2.5)
# เพิ่ม Colorbar (แสดง Magnitude)
# quiver ไม่มี colorbar ตรง ๆ ต้องใช้ ScalarMappable
from matplotlib.cm import ScalarMappable
from matplotlib.colors import Normalize
magnitude = np.sqrt(U**2 + V**2 + W**2)
sm = ScalarMappable(cmap='viridis', norm=Normalize(vmin=magnitude.min(), vmax=magnitude.max()))
sm.set_array([])
cbar = plt.colorbar(sm, ax=ax, shrink=0.6, pad=0.1)
cbar.set_label('Vector Magnitude', fontsize=11)
plt.show()
ตัวอย่าง: Vortex Field (สนามเกลียว)
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
plt.rcParams["figure.figsize"] = [12, 10]
plt.rcParams["figure.autolayout"] = True
n = 8
x = np.linspace(-3, 3, n)
y = np.linspace(-3, 3, n)
z = np.linspace(-3, 3, n)
X, Y, Z = np.meshgrid(x, y, z, indexing='ij')
# Vortex: หมุนรอบแกน Z
R = np.sqrt(X**2 + Y**2)
U = -Y / (R + 1e-6) # หลีกเลี่ยงหารศูนย์
V = X / (R + 1e-6)
W = 0.1 * Z # เล็กน้อยตาม Z
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
# ใช้สีตาม Magnitude
magnitude = np.sqrt(U**2 + V**2 + W**2)
colors = plt.cm.plasma(magnitude / magnitude.max())
ax.quiver(X, Y, Z, U, V, W,
length=0.4, normalize=True,
colors=colors, linewidth=1.5,
arrow_length_ratio=0.3)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
ax.set_title('3D Vortex Vector Field', fontsize=16)
ax.set_xlim(-3.5, 3.5)
ax.set_ylim(-3.5, 3.5)
ax.set_zlim(-3.5, 3.5)
plt.show()
ผลลัพธ์
กราฟ 3D แสดงลูกศรเวกเตอร์ที่แต่ละจุดในพื้นที่ 3 มิติ สีและทิศทางแสดงลักษณะของ Field
พารามิเตอร์สำคัญของ ax.quiver() 3D
| พารามิเตอร์ | คำอธิบาย |
|---|---|
X, Y, Z | ตำแหน่งจุดเริ่มต้น (Meshgrid) |
U, V, W | องค์ประกอบเวกเตอร์ (Delta X, Y, Z) |
length | ความยาวลูกศร (Data Units) |
normalize | True = ทำให้ลูกศรทุกอันยาวเท่ากัน |
arrow_length_ratio | อัตราส่วนหัวลูกศรต่อความยาว (Default 0.3) |
colors | สีแต่ละลูกศร (Array หรือ Colormap) |
pivot | 'tail', 'middle', 'tip' - จุดหมุนลูกศร |
คำแนะนำ
- ใช้
normalize=Trueร่วมlengthเพื่อควบคุมขนาดลูกศรให้สม่ำเสมอ - Grid ขนาดใหญ่ (n > 10) จะทำให้ลูกศรหนาแน่นและช้า ใช้ n=5-8 สำหรับแสดงผล
- ใช้
alphaเพื่อให้มองทะลุได้เมื่อลูกศรทับซ้อน - Colorbar ต้องสร้างแยกด้วย ScalarMappable เนื่องจาก quiver ไม่รองรับโดยตรง