การวาดเส้นที่มีลูกศรชี้ทิศทาง (Arrow-like Line Style) ใน Matplotlib ทำได้ด้วยเมธอด quiver() ซึ่งออกแบบมาสำหรับ Vector Field แต่ใช้วาดเส้นทางกับลูกศรได้ดี
หลักการ quiver()
quiver(X, Y, U, V) วาดลูกศรจากจุด (X, Y) ไปยัง (X+U, Y+V) โดย:
- X, Y: ตำแหน่งเริ่มต้นลูกศร
- U, V: เวกเตอร์ทิศทาง/ความยาว (Delta X, Delta Y)
- angles='xy', scale_units='xy', scale=1: ใช้ Data Coordinates โดยตรง
ตัวอย่าง: วาดเส้นโค้งพร้อมลูกศรชี้ทิศทาง
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams["figure.figsize"] = [10, 6]
plt.rcParams["figure.autolayout"] = True
# ข้อมูลเส้นโค้ง
x = np.linspace(-5, 5, 50)
y = np.sin(x)
fig, ax = plt.subplots()
# วาดเส้นโค้งพื้นหลัง
ax.plot(x, y, 'k-', linewidth=1, alpha=0.3, label='Path')
# คำนวณ Vector สำหรับ quiver (ทิศทางเส้นโค้ง)
# ใช้จุดกึ่งกลางระหว่างจุดข้อมูล
x_mid = (x[:-1] + x[1:]) / 2
y_mid = (y[:-1] + y[1:]) / 2
u = x[1:] - x[:-1] # Delta X
v = y[1:] - y[:-1] # Delta Y
# วาดลูกศรทุก 3 จุด (ไม่หนาแน่นเกินไป)
step = 3
ax.quiver(x_mid[::step], y_mid[::step],
u[::step], v[::step],
angles='xy', scale_units='xy', scale=1,
color='red', width=0.005, headwidth=3, headlength=4,
label='Direction')
ax.set_xlim(-5.5, 5.5)
ax.set_ylim(-1.5, 1.5)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_title('Arrow-like Line Style with quiver()', fontsize=14)
ax.legend()
ax.grid(True, alpha=0.3)
plt.show()
ตัวอย่าง: ลูกศรระหว่างจุดข้อมูล (Annotate Style)
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams["figure.figsize"] = [10, 6]
plt.rcParams["figure.autolayout"] = True
x = np.array([1, 2, 3, 4, 5])
y = np.array([2, 3, 1, 4, 2])
fig, ax = plt.subplots()
ax.plot(x, y, 'ko-', linewidth=2, markersize=8)
# วาดลูกศรระหว่างจุดต่อเนื่อง
for i in range(len(x) - 1):
ax.annotate('',
xy=(x[i+1], y[i+1]), xycoords='data',
xytext=(x[i], y[i]), textcoords='data',
arrowprops=dict(arrowstyle='->', color='blue', lw=2,
mutation_scale=15, shrinkA=5, shrinkB=5))
ax.set_title('Arrows Between Data Points (annotate)', fontsize=14)
ax.grid(True, alpha=0.3)
plt.show()
ตัวอย่าง: Fancy Arrow Patch (ควบคุมรายละเอียดสูง)
from matplotlib.patches import FancyArrowPatch
import matplotlib.pyplot as plt
import numpy as np
fig, ax = plt.subplots(figsize=(10, 6))
x = np.linspace(0, 10, 20)
y = np.sin(x)
ax.plot(x, y, 'k-', alpha=0.3)
# สร้าง FancyArrowPatch แบบกำหนดเอง
for i in range(0, len(x)-1, 2):
arrow = FancyArrowPatch(
posA=(x[i], y[i]),
posB=(x[i+1], y[i+1]),
arrowstyle='fancy,head_width=0.3,head_length=0.5,tail_width=0.1',
color='crimson',
linewidth=2,
mutation_scale=20,
shrinkA=3, shrinkB=3
)
ax.add_patch(arrow)
ax.set_title('FancyArrowPatch for Custom Arrow Styles', fontsize=14)
ax.grid(True, alpha=0.3)
plt.show()
สรุปวิธีการเลือกใช้
| วิธี | เหมาะสำหรับ | ความยืดหยุ่น |
|---|---|---|
| quiver() | Vector Field, หลายลูกศรพร้อมกัน, ข้อมูลเป็น Array | สูง |
| annotate() | ลูกศรเดี่ยว, ชี้จากจุดไปจุด, มีข้อความประกอบ | สูงมาก |
| FancyArrowPatch | ลูกศรโค้ง, รูปทรงซับซ้อน, Animation | สูงสุด |
| Arrow (patches.Arrow) | ลูกศรตรงง่ายๆ | ต่ำ |
คำแนะนำ
- ใช้
angles='xy', scale_units='xy', scale=1ใน quiver เพื่อให้ 1 Unit = 1 Data Unit widthควบคุมความหนาเส้น,headwidth,headlengthควบคุมหัวลูกศร- สำหรับเส้นโค้ง ใช้ annotate กับ
connectionstyle='arc3,rad=0.3'จะได้ลูกศรโค้งตามเส้น