01ภาพรวมของกราฟนี้
Hive plot จัดโหนดเข้าแกนตรงสองถึงสามแกนตามบทบาท แล้ววางตำแหน่งบนแกนตามค่าที่เลือก จุดแข็งคือตำแหน่งทุกจุดมีความหมายและภาพเดิมซ้ำได้เสมอ ต่างจาก force-directed ที่ตำแหน่งไม่มีความหมาย แลกกับการที่ต้องมีเกณฑ์จัดบทบาทที่ดีมาก่อน
เปรียบเทียบให้เห็นภาพ
เหมือนแผนผังที่นั่งในงานแต่งที่จัดคนตามฝ่ายเจ้าบ่าว ฝ่ายเจ้าสาว และเพื่อนร่วมงาน ซึ่งตำแหน่งบอกความสัมพันธ์จริง ๆ
ใช้ที่ไหนบ้าง — เครือข่ายที่โหนดมีบทบาทชัดเจนอยู่แล้ว เช่น เครือข่ายยีนที่แบ่งตามหน้าที่ หรือเครือข่ายองค์กรที่แบ่งตามแผนก
สร้างอย่างไร
- ขั้นที่ 1กำหนดเกณฑ์แบ่งโหนดเป็นสองถึงสามบทบาท
- ขั้นที่ 2เลือกค่าที่ใช้จัดลำดับบนแกน
- ขั้นที่ 3วางโหนดบนแกนตามค่านั้น
- ขั้นที่ 4ลากเส้นโค้งเชื่อมข้ามแกน
ตัวอย่างคลาสสิก · Hive plot ในงานวิเคราะห์เครือข่ายจีโนม
Martin Krzywinski เสนอ hive plot เพื่อแก้ปัญหาที่เครือข่ายชีววิทยาวาดด้วย force-directed แล้วได้ภาพต่างกันทุกครั้ง เมื่อจัดยีนเข้าแกนตามหน้าที่ที่รู้อยู่แล้ว ภาพก็กลายเป็นสิ่งที่เทียบข้ามการทดลองได้จริง
02อธิบายภาษาคนเข้าใจง่าย ๆ
ปัญหาที่ค้างอยู่ของ force-directed graph คือตำแหน่งไม่มีความหมาย ซึ่งทำให้ภาพเดิมซ้ำไม่ได้และผู้อ่านตีความผิดเสมอ
Hive plot แก้ด้วยการเลิกให้คอมพิวเตอร์หาตำแหน่งเอง แล้วให้คนกำหนดกติกาแทน โดยแบ่งโหนดเข้าแกนตามบทบาท และวางบนแกนตามค่าที่เลือก
ผลคือตำแหน่งทุกจุดอธิบายได้ และถ้าข้อมูลเดิมก็ได้ภาพเดิมเสมอ ซึ่งแปลว่าเปรียบเทียบเครือข่ายสองชุดข้างกันได้จริง อันเป็นสิ่งที่ force-directed ทำไม่ได้
ราคาที่จ่ายอย่างแรกคือคุณภาพของภาพขึ้นกับเกณฑ์จัดบทบาททั้งหมด ถ้าเกณฑ์ไม่มีความหมาย ภาพจะดูเป็นระเบียบสวยงามแต่ไม่บอกอะไรเลย ซึ่งอันตรายกว่าภาพที่ดูรก
อย่างที่สองคือมันใช้ได้กับเครือข่ายที่มีบทบาทชัดเจนอยู่แล้วเท่านั้น ซึ่งเป็นกรณีที่ไม่ได้พบบ่อย จึงเป็นกราฟเฉพาะทางมากกว่าจะเป็นตัวเลือกทั่วไป
03ข้อมูลที่ต้องใช้
คอลัมน์ที่ต้องเตรียม
| คอลัมน์ | ทำหน้าที่ | ชนิด | เข้ารหัสด้วย | จำนวนค่าที่เหมาะ | หมายเหตุ |
|---|---|---|---|---|---|
source | โหนดต้นทาง | โหนด | angle | 10–120 โหนด | ต้องมีเกณฑ์จัดเข้าแกนได้ |
target | โหนดปลายทาง | โหนด | angle | ชุดเดียวกับ source | เส้นเชื่อมข้ามแกนเป็นเส้นโค้ง |
valueไม่บังคับ | น้ำหนักความสัมพันธ์ | ตัวเลขต่อเนื่อง | size | บวกเท่านั้น | ควบคุมความหนาของเส้น |
ต้องเตรียมข้อมูลอย่างไรก่อนวาด
- ★ กำหนดเกณฑ์จัดบทบาทที่มีความหมายก่อนวาด
- เลือกตัวแปรจัดลำดับบนแกนและระบุในคำอธิบาย
- ตัดสินใจว่าจะแสดงเส้นภายในแกนเดียวกันอย่างไร
ค่าที่หายไป — โหนดที่จัดเข้าบทบาทไม่ได้ต้องแยกออกและรายงานจำนวน ไม่ยัดเข้าแกนใดแกนหนึ่งมั่ว
สเกลของแกน — ค่าที่ใช้จัดลำดับบนแกนต้องเป็นตัวเดียวกันทุกแกนเพื่อให้เทียบข้ามแกนได้
กราฟจะเริ่มพังเมื่อไร
เกิน 4 แกน ผู้อ่านตามไม่ทันว่าเส้นไหนไปแกนไหน
หน้าตาไฟล์ที่ต้องเตรียม
source,target,value
เข้าชมเว็บ,ดูสินค้า,7975
เข้าชมเว็บ,ออกทันที,4078
…04อ่านแล้วเห็นอะไร
สิ่งที่เห็นได้จากภาพ
- รูปแบบการเชื่อมต่อระหว่างบทบาท
- บทบาทคู่ไหนเชื่อมกันมากที่สุด
- โหนดที่เชื่อมข้ามหลายบทบาท
สิ่งที่กราฟนี้ตอบไม่ได้
- ★ ถ้าเกณฑ์จัดบทบาทไม่มีความหมาย ภาพจะดูเป็นระเบียบแต่ไม่บอกอะไร
- ตามเส้นทีละเส้นได้ยากเมื่อเส้นโค้งซ้อนกันใกล้ศูนย์กลาง
อ่านตามลำดับนี้
- อ่านชื่อแกนก่อนว่าแต่ละแกนคือบทบาทอะไร
- ดูว่าเส้นส่วนใหญ่พาดระหว่างแกนคู่ไหน
- ดูโหนดที่มีเส้นออกไปทุกแกน
คำถามที่ตอบได้
- บทบาทไหนเชื่อมกับบทบาทไหนมากที่สุด
- มีโหนดที่เชื่อมข้ามทุกบทบาทไหม
- โครงสร้างการเชื่อมต่อเปลี่ยนไปไหมเมื่อเทียบสองช่วงเวลา
สัญญาณว่ามีอะไรผิด
- ไม่ระบุว่าจัดบทบาทด้วยเกณฑ์อะไร
- ใช้เกินสามแกนจนตามไม่ทัน
- ไม่ระบุว่าตำแหน่งบนแกนมาจากค่าอะไร
05เหมาะกับการนำเสนอแบบไหน
ทำอย่างไรให้คนอ่านได้ข้อสรุปโดยไม่ต้องบรรยาย
- เขียนชื่อบทบาทกำกับที่ปลายแกนทุกแกน
- ระบุว่าตำแหน่งบนแกนมาจากค่าอะไร
- ใช้สีตามแกนต้นทางเพื่อให้ตามเส้นได้
รูปแบบชื่อกราฟที่ควรใช้
เครือข่าย <จำนวน> โหนด จัดตาม <เกณฑ์บทบาท>
06เอาไปใช้ต่อ
โค้ดทุกชิ้นอ่านไฟล์ hive-plot-sample.csv ชุดเดียวกับที่ Playground ใช้ และตัวเลขในโค้ดเปลี่ยนตามค่าที่คุณปรับด้านล่าง
# ติดตั้ง: pip install "matplotlib==3.10.*" "pandas==2.*"
# ดาวน์โหลด hive-plot-sample.csv จากหน้านี้ แล้ววางไว้ข้างสคริปต์
import matplotlib
matplotlib.use("Agg") # รันแบบไม่มีหน้าจอ ถ้ารันในเครื่องตัวเองลบบรรทัดนี้ได้
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import networkx as nx
C1, C2, C3 = "#2a78d6", "#eb6834", "#1baf7a" # palette ของคลัง เปลี่ยนเป็นสีองค์กรได้
INK, SURFACE = "#0b0b0b", "#fcfcfb"
df = pd.read_csv("hive-plot-sample.csv")
df["value"] = pd.to_numeric(df["value"], errors="coerce")
NOTE = "axes" # ← ค่าจาก Playground
fig, ax = plt.subplots(figsize=(7.6, 4.2), facecolor=SURFACE)
ax.set_facecolor(SURFACE)
G = nx.from_pandas_edgelist(df, "source", "target", edge_attr="value")
nodes = list(G)
role = {n: G.degree(n) % 3 for n in nodes} # แทนที่ด้วยเกณฑ์จริงของคุณ
pos = {}
for ax_i in range(3):
members = sorted([n for n in nodes if role[n] == ax_i], key=lambda n: G.degree(n))
a = ax_i / 3 * 2 * np.pi - np.pi / 2
for i, n in enumerate(members):
r = 0.3 + 0.7 * (i / max(1, len(members) - 1))
pos[n] = (np.cos(a) * r, np.sin(a) * r)
for ax_i in range(3):
a = ax_i / 3 * 2 * np.pi - np.pi / 2
ax.plot([np.cos(a) * 0.25, np.cos(a) * 1.05], [np.sin(a) * 0.25, np.sin(a) * 1.05],
color=PALETTE[ax_i], linewidth=2.5)
for a_, b_ in G.edges():
ax.plot(*zip(pos[a_], (0, 0), pos[b_]), color="#c9c6bd", linewidth=1.2, alpha=0.7)
for n in nodes:
ax.plot(*pos[n], "o", markersize=6, color=PALETTE[role[n]])
ax.set_aspect("equal"); ax.axis("off")
ax.spines[["top", "right"]].set_visible(False) # ลดเส้นที่ไม่ได้ให้ข้อมูล
fig.tight_layout()
fig.savefig("hive-plot.png", dpi=160)
print("เขียน hive-plot.png แล้ว ·", len(df), "แถว")07ลองเล่นเพื่อเข้าใจ
ต้องมีเกณฑ์จัดโหนดเข้าแกนที่มีความหมายก่อน ไม่อย่างนั้นภาพจะดูเป็นระเบียบทั้งที่ไม่ได้บอกอะไร
ดูข้อมูลเป็นตาราง (9 แถว)
| โหนด | บทบาท |
|---|---|
| เข้าชมเว็บ | บทบาทที่ 2 |
| ดูสินค้า | บทบาทที่ 3 |
| ออกทันที | บทบาทที่ 3 |
| ใส่ตะกร้า | บทบาทที่ 1 |
| ออกกลางทาง | บทบาทที่ 2 |
| กรอกที่อยู่ | บทบาทที่ 3 |
| ทิ้งตะกร้า | บทบาทที่ 2 |
| ชำระเงินสำเร็จ | บทบาทที่ 3 |
| ชำระไม่สำเร็จ | บทบาทที่ 2 |
ลองแล้วจะเห็นอะไร
- สังเกตอะไร: เทียบกับหน้า force-directed-graph ที่ใช้ข้อมูลชุดเดียวกัน จะเห็นว่าที่นี่ตำแหน่งอธิบายได้และรันกี่ครั้งก็ได้ภาพเดิม
ข้อควรระวัง
- ★ ใช้เกณฑ์จัดบทบาทที่ไม่มีความหมาย ทำให้ภาพดูเป็นระเบียบแต่ไม่บอกอะไร
- ไม่บอกผู้อ่านว่าแกนแบ่งตามอะไรและตำแหน่งบนแกนมาจากค่าอะไร
- ใช้เกินสามแกนจนผู้อ่านตามเส้นไม่ทัน
- เลือกกราฟนี้ทั้งที่เครือข่ายไม่มีบทบาทชัดเจนอยู่แล้ว
เมื่อไหร่ไม่ควรใช้กราฟนี้
- โหนดไม่มีบทบาทที่แบ่งได้ชัดเจน→ใช้แทน: force-directed-graph
- เครือข่ายหนาแน่นมาก→ใช้แทน: adjacency-matrix
- ผู้อ่านไม่คุ้นกับกราฟเฉพาะทาง→ใช้แทน: chord-diagram ที่อ่านง่ายกว่า