Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Python

การทำงานของ Matplotlib.pyplot.quiver อย่างละเอียด

matplotlib.pyplot.quiver() ใช้สำหรับวาด Vector Field (สนามเวกเตอร์) โดยแสดงลูกศรที่แต่ละจุด (X, Y) ชี้ไปในทิศทาง (U, V) ความเข้าใจพารามิเตอร์สำคัญคือ angles, scale_units, scale

Signature และพารามิเตอร์หลัก

quiver(X, Y, U, V, 
       angles='uv', scale_units='xy', scale=1, 
       width=None, headwidth=3, headlength=5, headaxislength=4.5,
       color=None, cmap=None, alpha=1, pivot='tail', ...)

ความหมายพารามิเตอร์สำคัญ

พารามิเตอร์คำอธิบาย
X, Yตำแหน่งจุดเริ่มต้นลูกศร (1D หรือ 2D Array)
U, Vองค์ประกอบเวกเตอร์: U = ΔX, V = ΔY
angles'uv' (Default): มุมจาก U,V ใน Screen Coords | 'xy': มุมจาก U,V ใน Data Coords
scale_units'xy': 1 unit = 1 data unit | 'width': 1 unit = Axes width | 'height', 'dots', 'inches'
scaleตัวคูณสเกล: ความยาวลูกศร = sqrt(U²+V²) / scale (ถ้า scale_units='xy')
pivot'tail' (Default): จุดเริ่มต้นที่หาง | 'mid': กลาง | 'tip': หัวลูกศร
widthความหนาของลูกศร (ในหน่วย scale_units)

ตัวอย่าง: ทดสอบ angles และ scale_units

import numpy as np
import matplotlib.pyplot as plt

plt.rcParams["figure.figsize"] = [14, 10]
plt.rcParams["figure.autolayout"] = True

# ข้อมูล Vector Field เรียบง่าย
soa = np.array([
    [0, 0, 2, 1],   # X, Y, U, V
    [0, 0, 3, 3],
    [0, 0, 1, 4],
    [2, 2, -1, 2],
    [3, 1, -2, -1],
])
X, Y, U, V = zip(*soa)

fig, axes = plt.subplots(2, 2, figsize=(12, 10))

# 1. Default: angles='uv', scale_units='xy', scale=1
ax = axes[0, 0]
ax.quiver(X, Y, U, V, angles='uv', scale_units='xy', scale=1, color='red')
ax.set_title("angles='uv', scale_units='xy', scale=1\n(Default: Screen Angle, Data Scale)")
ax.set_xlim(-1, 5); ax.set_ylim(-1, 5); ax.grid(True); ax.set_aspect('equal')

# 2. angles='xy', scale_units='xy', scale=1 (Data Coordinates)
ax = axes[0, 1]
ax.quiver(X, Y, U, V, angles='xy', scale_units='xy', scale=1, color='blue')
ax.set_title("angles='xy', scale_units='xy', scale=1\n(Data Angle, Data Scale) - RECOMMENDED")
ax.set_xlim(-1, 5); ax.set_ylim(-1, 5); ax.grid(True); ax.set_aspect('equal')

# 3. angles='xy', scale_units='xy', scale=2 (ครึ่งความยาว)
ax = axes[1, 0]
ax.quiver(X, Y, U, V, angles='xy', scale_units='xy', scale=2, color='green')
ax.set_title("angles='xy', scale_units='xy', scale=2\n(Half Length)")
ax.set_xlim(-1, 5); ax.set_ylim(-1, 5); ax.grid(True); ax.set_aspect('equal')

# 4. angles='xy', scale_units='width', scale=0.05 (Relative to Axes Width)
ax = axes[1, 1]
ax.quiver(X, Y, U, V, angles='xy', scale_units='width', scale=0.05, color='purple')
ax.set_title("angles='xy', scale_units='width', scale=0.05\n(Relative to Axes Width)")
ax.set_xlim(-1, 5); ax.set_ylim(-1, 5); ax.grid(True); ax.set_aspect('equal')

plt.suptitle('quiver() Parameter Comparison', fontsize=16)
plt.show()

ผลลัพธ์

4 Subplots แสดงความแตกต่างของ angles และ scale_units:

  • angles='uv': ลูกศรชี้ตามมุมจอภาพ (Square Pixels) - ทูกันหาก Aspect Ratio ไม่ใช่ 1:1
  • angles='xy', scale_units='xy', scale=1: แนะนำมากที่สุด - ลูกศรชี้ถูกต้องใน Data Space, 1 Unit = 1 Data Unit
  • scale=2: ลูกศรสั้นลงครึ่งหนึ่ง
  • scale_units='width': ความยาวสัมพัทธ์กับความกว้าง Axes

การใช้งานจริง: Vector Field จากฟังก์ชัน

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(-3, 3, 15)
y = np.linspace(-3, 3, 15)
X, Y = np.meshgrid(x, y)

# Vector Field: F(x,y) = (-y, x)  (Rotation)
U = -Y
V = X

fig, ax = plt.subplots(figsize=(8, 8))
ax.quiver(X, Y, U, V, 
          angles='xy', scale_units='xy', scale=3,  # scale=3: ลูกศรยาว 1/3 ของ Vector จริง
          color=plt.cm.hsv(np.arctan2(V, U) / (2*np.pi)),  # สีตามมุม
          width=0.005, headwidth=3)

ax.set_aspect('equal')
ax.set_xlim(-3.5, 3.5)
ax.set_ylim(-3.5, 3.5)
ax.set_title('Rotation Field: F(x,y) = (-y, x)', fontsize=14)
plt.show()

สรุป Best Practice

  • ใช้ angles='xy', scale_units='xy', scale=1 สำหรับ Vector Field ใน Data Coordinates
  • ใช้ scale > 1 หากลูกศรยาวเกิน/ทับซ้อน (เช่น scale=3, 5, 10)
  • ใช้ pivot='mid' หากต้องการลูกศรกึ่งกลางอยู่ที่จุดข้อมูล
  • กำหนด width ให้เหมาะสม (0.003-0.01) ไม่งั้นลูกศรจะหนาเกินไป