01ภาพรวมของกราฟนี้
Arc diagram วางโหนดเรียงกันบนเส้นตรงแล้วลากส่วนโค้งเชื่อมคู่ที่เกี่ยวข้อง จุดแข็งคือรักษาลำดับของโหนดไว้ ซึ่งเป็นสิ่งที่กราฟเครือข่ายแบบจัดวางอิสระทำลายทิ้ง จึงเหมาะเมื่อลำดับมีความหมาย เช่น เวลา ตำแหน่งในข้อความ หรือขั้นตอน
เปรียบเทียบให้เห็นภาพ
เหมือนแผนที่รถไฟฟ้าที่สถานีเรียงตามเส้นทางจริง แล้วมีเส้นโค้งบอกว่าสถานีไหนเชื่อมถึงกันโดยตรง
ใช้ที่ไหนบ้าง — การอ้างอิงระหว่างบทในหนังสือ การเชื่อมโยงระหว่างเหตุการณ์ตามเวลา หรือความสัมพันธ์ระหว่างตัวละครตามลำดับการปรากฏ
สร้างอย่างไร
- ขั้นที่ 1เรียงโหนดบนเส้นตรงตามลำดับที่มีความหมาย
- ขั้นที่ 2ลากส่วนโค้งเชื่อมคู่ที่เกี่ยวข้อง
- ขั้นที่ 3ให้ความหนาของโค้งแปรตามน้ำหนัก
- ขั้นที่ 4วางโค้งไว้ด้านเดียวหรือสองด้านตามทิศทาง
ตัวอย่างคลาสสิก · Arc diagram ของโครงสร้างซ้ำในบทเพลง
Martin Wattenberg สร้าง The Shape of Song ที่แสดงท่อนที่ซ้ำกันในบทเพลงเป็นส่วนโค้งเชื่อมระหว่างตำแหน่งบนแกนเวลาของเพลง รูปแบบนี้ตรงกับข้อมูลพอดีเพราะเวลาในเพลงมีลำดับที่ชัดเจน และทำให้เห็นโครงสร้างของบทเพลงที่การฟังอย่างเดียวจับไม่ได้
02อธิบายภาษาคนเข้าใจง่าย ๆ
กราฟเครือข่ายทั่วไปจัดวางโหนดอย่างอิสระเพื่อให้เส้นตัดกันน้อยที่สุด ซึ่งดีเมื่อโหนดไม่มีลำดับ แต่ทำลายข้อมูลทิ้งเมื่อลำดับมีความหมาย
Arc diagram เลือกทางตรงข้าม คือตรึงโหนดไว้บนเส้นตรงตามลำดับที่มีความหมาย แล้วยอมให้เส้นเชื่อมโค้งข้ามกันแทน
ผลคือผู้อ่านได้ข้อมูลสองชั้น ชั้นแรกคือลำดับของโหนดซึ่งอ่านจากแกนนอน ชั้นที่สองคือการเชื่อมโยงซึ่งอ่านจากส่วนโค้ง
รูปแบบที่อ่านได้ทันทีคือระยะของการเชื่อม โค้งสั้นคือการเชื่อมกับเพื่อนบ้านใกล้ ๆ ส่วนโค้งยาวคือการเชื่อมข้ามไปไกล ซึ่งมักเป็นสิ่งที่น่าสนใจที่สุด
ข้อจำกัดคือเมื่อมีเส้นเยอะ ส่วนโค้งจะทับกันจนอ่านยาก และเพราะทุกโค้งอยู่ด้านเดียวกัน โค้งใหญ่จะครอบโค้งเล็กไว้ ทางแก้คือแยกทิศทางไปคนละด้านของเส้น
03ข้อมูลที่ต้องใช้
คอลัมน์ที่ต้องเตรียม
| คอลัมน์ | ทำหน้าที่ | ชนิด | เข้ารหัสด้วย | จำนวนค่าที่เหมาะ | หมายเหตุ |
|---|---|---|---|---|---|
source | โหนดต้นทาง | โหนด | x | 5–40 โหนด | ★ ลำดับของโหนดบนแกนต้องมีความหมาย |
target | โหนดปลายทาง | โหนด | x | ชุดเดียวกับต้นทาง | ระยะบนแกนคือระยะของการเชื่อม |
valueไม่บังคับ | น้ำหนักของการเชื่อม | ตัวเลขต่อเนื่อง | size | บวกเท่านั้น | ใช้กำหนดความหนาของโค้ง |
ต้องเตรียมข้อมูลอย่างไรก่อนวาด
- กำหนดลำดับของโหนดที่มีความหมายและเขียนเหตุผล
- รวมเส้นซ้ำระหว่างคู่เดียวกัน
- ตัดสินใจว่าจะแยกทิศทางไปคนละด้านของเส้นหรือไม่
ค่าที่หายไป — โหนดที่ไม่มีการเชื่อมเลยต้องแสดงไว้บนแกนด้วย เพื่อให้เห็นว่ามีอยู่แต่โดดเดี่ยว
สเกลของแกน — ระยะบนแกนนอนควรสะท้อนลำดับจริง ถ้าลำดับเป็นเวลาก็ควรวางตามเวลาจริงไม่ใช่เรียงเท่า ๆ กัน
กราฟจะเริ่มพังเมื่อไร
เกิน 60 เส้น ส่วนโค้งจะทับกันจนอ่านไม่ได้ — ใช้ adjacency-matrix
หน้าตาไฟล์ที่ต้องเตรียม
source,target,value
เข้าชมเว็บ,ดูสินค้า,7975
เข้าชมเว็บ,ออกทันที,4078
…04อ่านแล้วเห็นอะไร
สิ่งที่เห็นได้จากภาพ
- โหนดที่มีการเชื่อมมากที่สุด
- การเชื่อมระยะไกลซึ่งมักน่าสนใจที่สุด
- กลุ่มโหนดที่เชื่อมกันเองหนาแน่น
- โหนดที่ไม่เชื่อมกับใครเลย
สิ่งที่กราฟนี้ตอบไม่ได้
- ไม่บอกโครงสร้างของกลุ่มย่อยได้ดีเท่ากราฟเครือข่ายแบบจัดวางอิสระ
- เมื่อเส้นเยอะจะทับกันจนตามเส้นเดียวไม่ได้
อ่านตามลำดับนี้
- ดูโหนดที่มีโค้งออกมากที่สุด
- มองหาโค้งที่ยาวผิดปกติ
- ดูบริเวณที่โค้งหนาแน่นซึ่งคือกลุ่มที่เชื่อมกันเอง
คำถามที่ตอบได้
- โหนดไหนเป็นศูนย์กลาง
- มีการเชื่อมข้ามไปไกลไหม
- โหนดที่อยู่ติดกันเชื่อมกันมากกว่าโหนดที่อยู่ไกลไหม
สัญญาณว่ามีอะไรผิด
- ลำดับของโหนดเรียงตามตัวอักษรโดยไม่มีเหตุผล ซึ่งทำลายจุดแข็งของกราฟนี้
- เส้นเกิน 60 เส้นจนทับกัน
05เหมาะกับการนำเสนอแบบไหน
ทำอย่างไรให้คนอ่านได้ข้อสรุปโดยไม่ต้องบรรยาย
- เขียนว่าลำดับของโหนดจัดตามอะไร
- เน้นโค้งที่เป็นประเด็นและทำเส้นอื่นจาง
- ใช้ความหนาแทนน้ำหนักและอธิบายไว้
รูปแบบชื่อกราฟที่ควรใช้
<โหนด> เชื่อมกับ <จำนวน> โหนด รวมถึงการเชื่อมข้ามไปยัง <โหนด> ที่อยู่ไกลออกไป
06เอาไปใช้ต่อ
โค้ดทุกชิ้นอ่านไฟล์ arc-diagram-sample.csv ชุดเดียวกับที่ Playground ใช้ และตัวเลขในโค้ดเปลี่ยนตามค่าที่คุณปรับด้านล่าง
# ติดตั้ง: pip install "matplotlib==3.10.*" "pandas==2.*"
# ดาวน์โหลด arc-diagram-sample.csv จากหน้านี้ แล้ววางไว้ข้างสคริปต์
import matplotlib
matplotlib.use("Agg") # รันแบบไม่มีหน้าจอ ถ้ารันในเครื่องตัวเองลบบรรทัดนี้ได้
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
from matplotlib.patches import Arc
C1, C2, C3 = "#2a78d6", "#eb6834", "#1baf7a" # palette ของคลัง เปลี่ยนเป็นสีองค์กรได้
INK, SURFACE = "#0b0b0b", "#fcfcfb"
df = pd.read_csv("arc-diagram-sample.csv")
df["value"] = pd.to_numeric(df["value"], errors="coerce")
NOTE = "span" # ← ค่าจาก Playground
fig, ax = plt.subplots(figsize=(7.6, 4.2), facecolor=SURFACE)
ax.set_facecolor(SURFACE)
nodes = list(dict.fromkeys(list(df["source"]) + list(df["target"])))
pos = {n: i for i, n in enumerate(nodes)} # ลำดับต้องมีความหมาย ไม่ใช่เรียงตามตัวอักษร
maxv = df["value"].max()
for _, r in df.iterrows():
x0, x1 = pos[r["source"]], pos[r["target"]]
ax.add_patch(Arc(((x0 + x1) / 2, 0), abs(x1 - x0), abs(x1 - x0) * 0.8,
theta1=0, theta2=180, lw=1.5 + r["value"] / maxv * 5,
color=plt.cm.Blues(0.35 + r["value"] / maxv * 0.55)))
ax.scatter(range(len(nodes)), [0] * len(nodes), s=80, color=C1, zorder=3)
ax.set_xticks(range(len(nodes))); ax.set_xticklabels(nodes, rotation=40, ha="right", fontsize=8)
ax.set_ylim(-0.3, len(nodes) * 0.45); ax.set_yticks([])
ax.spines[["left", "right", "top"]].set_visible(False)
ax.spines[["top", "right"]].set_visible(False) # ลดเส้นที่ไม่ได้ให้ข้อมูล
fig.tight_layout()
fig.savefig("arc-diagram.png", dpi=160)
print("เขียน arc-diagram.png แล้ว ·", len(df), "แถว")07ลองเล่นเพื่อเข้าใจ
ลำดับของโหนดบนแกนเปลี่ยนภาพทั้งหมด — ต้องเลือกลำดับที่มีความหมาย ไม่ใช่เรียงตามตัวอักษรโดยไม่คิด
ดูข้อมูลเป็นตาราง (8 แถว)
| จาก | ไป | น้ำหนัก |
|---|---|---|
| เข้าชมเว็บ | ดูสินค้า | 7,975 |
| เข้าชมเว็บ | ออกทันที | 4,078 |
| ดูสินค้า | ใส่ตะกร้า | 3,083 |
| ดูสินค้า | ออกกลางทาง | 5,112 |
| ใส่ตะกร้า | กรอกที่อยู่ | 1,952 |
| ใส่ตะกร้า | ทิ้งตะกร้า | 1,166 |
| กรอกที่อยู่ | ชำระเงินสำเร็จ | 1,418 |
| กรอกที่อยู่ | ชำระไม่สำเร็จ | 457 |
ลองแล้วจะเห็นอะไร
- สังเกตอะไร: มองหาโค้งที่ยาวที่สุด นั่นคือการเชื่อมระหว่างโหนดที่อยู่ห่างกันในลำดับ ซึ่งมักเป็นสิ่งที่น่าสนใจที่สุดในข้อมูลที่มีลำดับ
ข้อควรระวัง
- ★ เรียงโหนดตามตัวอักษรโดยไม่มีเหตุผล ซึ่งทำลายจุดแข็งเดียวของกราฟนี้
- ใส่เส้นเกิน 60 เส้นจนส่วนโค้งทับกัน
- วางโค้งไว้ด้านเดียวทั้งที่การไหลมีสองทิศทาง
- ไม่แสดงโหนดที่ไม่มีการเชื่อมเลย ทำให้ไม่รู้ว่ามีโหนดโดดเดี่ยวอยู่
เมื่อไหร่ไม่ควรใช้กราฟนี้
- โหนดไม่มีลำดับที่มีความหมาย→ใช้แทน: force-directed-graph
- มีเส้นเชื่อมเกิน 60 เส้น→ใช้แทน: adjacency-matrix
- สนใจปริมาณที่ไหลมากกว่าการเชื่อม→ใช้แทน: sankey-diagram