01ภาพรวมของกราฟนี้
Glyph plot แทนแต่ละรายการด้วยสัญลักษณ์ที่รูปร่างเข้ารหัสหลายตัวแปร ทำให้เทียบรูปร่างได้เร็วและหารายการที่ผิดจากพวกได้ง่าย แต่อ่านค่าไม่ได้เลย และช่องทางที่ใช้มีความไวต่างกันมาก ทำให้ตัวแปรบางตัวเด่นกว่าตัวอื่นโดยไม่ตั้งใจ
เปรียบเทียบให้เห็นภาพ
เหมือนป้ายทะเบียนที่แต่ละคันมีลายเฉพาะ ซึ่งจำและแยกได้เร็วแม้จะไม่ได้อ่านตัวอักษรทีละตัว
ใช้ที่ไหนบ้าง — สแกนหารายการที่ผิดจากพวกในชุดข้อมูลขนาดกลาง หรือแสดงโปรไฟล์ของหลายรายการพร้อมกันบนตารางหรือแผนที่
สร้างอย่างไร
- ขั้นที่ 1★ ปรับทุกตัวแปรเป็นสเกลเดียวกัน
- ขั้นที่ 2เลือกช่องทางที่มีความไวใกล้เคียงกัน
- ขั้นที่ 3วางสัญลักษณ์เรียงเป็นตารางตามเกณฑ์ที่มีความหมาย
- ขั้นที่ 4ใส่สัญลักษณ์อ้างอิงที่แสดงค่ากลางไว้เทียบ
ตัวอย่างคลาสสิก · Chernoff faces และการใช้ใบหน้าแทนข้อมูล
Herman Chernoff เสนอในปี 1973 ให้เข้ารหัสตัวแปรเป็นลักษณะของใบหน้า โดยอาศัยว่าคนจำและแยกใบหน้าได้เก่งเป็นพิเศษ แนวคิดนี้ถูกวิจารณ์อย่างหนักเพราะลักษณะใบหน้าแต่ละอย่างมีน้ำหนักทางอารมณ์ไม่เท่ากัน แต่ก็เป็นตัวอย่างที่ชัดที่สุดของหลักการที่ว่าการเลือกช่องทางคือการเลือกว่าตัวแปรไหนจะเด่น
02อธิบายภาษาคนเข้าใจง่าย ๆ
บางครั้งคำถามไม่ใช่ค่าเท่าไร แต่เป็นรายการไหนที่หน้าตาไม่เหมือนพวก ซึ่งเป็นงานที่สายตาคนเก่งมาก
Glyph plot ตอบโจทย์นั้นด้วยการทำให้แต่ละรายการมีรูปร่างของตัวเอง โดยเอาหลายตัวแปรมาควบคุมส่วนต่าง ๆ ของสัญลักษณ์
เมื่อวางเรียงเป็นตาราง ผู้อ่านจะกวาดสายตาได้เร็วมากและสะดุดกับสัญลักษณ์ที่ต่างจากเพื่อนบ้านทันที ซึ่งเร็วกว่าการอ่านตารางตัวเลขหลายเท่า
ปัญหาข้อแรกคืออ่านค่าไม่ได้เลย เพราะไม่มีแกนและไม่มีสเกลให้เทียบ ภาพนี้จึงบอกได้แค่ว่ารายการนี้ต่างจากรายการอื่น แต่บอกไม่ได้ว่าต่างกันเท่าไรและต่างที่มิติไหนกันแน่
ปัญหาข้อที่สองซึ่งร้ายกว่าคือช่องทางที่ใช้มีความไวไม่เท่ากัน ความยาวอ่านง่ายกว่ามุมมาก ดังนั้นตัวแปรที่ถูกจับคู่กับความยาวจะดูสำคัญกว่าตัวแปรที่จับคู่กับมุมโดยที่ไม่มีใครตั้งใจ
กรณีสุดขั้วที่โด่งดังคือ Chernoff faces ที่ใช้ใบหน้าเป็นสัญลักษณ์ ซึ่งอาศัยความสามารถพิเศษของคนในการจำใบหน้า แต่ก็ถูกวิจารณ์หนักเพราะขนาดปากกับความโค้งของคิ้วมีน้ำหนักทางอารมณ์ต่างกันมาก
03ข้อมูลที่ต้องใช้
คอลัมน์ที่ต้องเตรียม
| คอลัมน์ | ทำหน้าที่ | ชนิด | เข้ารหัสด้วย | จำนวนค่าที่เหมาะ | หมายเหตุ |
|---|---|---|---|---|---|
item | รายการ | หมวดหมู่ | text | 5–60 รายการ | แต่ละรายการเป็นหนึ่งสัญลักษณ์ |
groupไม่บังคับ | กลุ่ม | หมวดหมู่ | color | 2–6 กลุ่ม | ใช้สีบอกกลุ่ม |
ราคา | มิติที่เข้ารหัส | ตัวเลขต่อเนื่อง | size | 3–7 มิติ | ★ เกินเจ็ดมิติแล้วสัญลักษณ์อ่านไม่ออก |
ต้องเตรียมข้อมูลอย่างไรก่อนวาด
- ★ ปรับทุกตัวแปรเป็นสเกลเดียวกัน
- จับคู่ตัวแปรกับช่องทางอย่างตั้งใจโดยคำนึงถึงความไว
- เลือกเกณฑ์เรียงสัญลักษณ์ที่มีความหมาย
ค่าที่หายไป — มิติที่ไม่มีค่าต้องทำให้เห็นชัดว่าหายไป ไม่ใช่ปล่อยให้ดูเหมือนค่าต่ำสุด
สเกลของแกน — ทุกมิติต้องใช้ช่วงเดียวกัน และควรมีสัญลักษณ์อ้างอิงที่แสดงค่ากลางไว้ให้เทียบ
กราฟจะเริ่มพังเมื่อไร
เกิน 60 รายการหรือเกิน 7 มิติ สัญลักษณ์อ่านไม่ออก
หน้าตาไฟล์ที่ต้องเตรียม
item,group,ราคา,ความเร็ว,ความจุ,น้ำหนัก,คะแนนรีวิว
รุ่น A,รุ่นประหยัด,167,48.5,17.6,30.9,3.17
รุ่น B,รุ่นมาตรฐาน,301,55.7,30.4,20,4.09
…04อ่านแล้วเห็นอะไร
สิ่งที่เห็นได้จากภาพ
- รายการที่รูปร่างต่างจากพวกอย่างชัดเจน
- กลุ่มของรายการที่รูปร่างคล้ายกัน
- มิติที่แปรผันมากที่สุดข้ามรายการ
สิ่งที่กราฟนี้ตอบไม่ได้
- ★ ค่าของตัวแปรใดตัวแปรหนึ่ง เพราะอ่านจากรูปร่างซึ่งไม่มีสเกลให้อ่าน
- ★ ตัวแปรที่จับคู่กับช่องทางที่อ่อนไหวน้อยจะถูกมองข้าม
- ความต่างที่ละเอียด
อ่านตามลำดับนี้
- อ่านคำอธิบายว่าส่วนไหนของสัญลักษณ์แทนอะไร
- กวาดสายตาหาสัญลักษณ์ที่ต่างจากเพื่อนบ้าน
- เทียบกับสัญลักษณ์อ้างอิงที่แสดงค่ากลาง
คำถามที่ตอบได้
- รายการไหนผิดจากพวก
- มีรายการไหนที่โปรไฟล์คล้ายกันบ้าง
- โปรไฟล์โดยรวมของรายการนี้เป็นอย่างไร
สัญญาณว่ามีอะไรผิด
- ไม่มีคำอธิบายว่าส่วนไหนแทนอะไร
- ใช้เกินเจ็ดมิติ
- จับคู่ตัวแปรสำคัญกับช่องทางที่อ่อนไหวน้อย
- ไม่มีสัญลักษณ์อ้างอิง
05เหมาะกับการนำเสนอแบบไหน
ทำอย่างไรให้คนอ่านได้ข้อสรุปโดยไม่ต้องบรรยาย
- ★ ใส่สัญลักษณ์อ้างอิงพร้อมคำอธิบายว่าส่วนไหนแทนอะไร
- ติดชื่อรายการใต้ทุกสัญลักษณ์
- ทำเครื่องหมายรายการที่ผิดปกติให้เด่น
รูปแบบชื่อกราฟที่ควรใช้
โปรไฟล์ <จำนวน> รายการใน <จำนวน> มิติ โดย <รายการ> ต่างจากพวกมากที่สุด
06เอาไปใช้ต่อ
โค้ดทุกชิ้นอ่านไฟล์ glyph-plot-sample.csv ชุดเดียวกับที่ Playground ใช้ และตัวเลขในโค้ดเปลี่ยนตามค่าที่คุณปรับด้านล่าง
# ติดตั้ง: pip install "matplotlib==3.10.*" "pandas==2.*"
# ดาวน์โหลด glyph-plot-sample.csv จากหน้านี้ แล้ววางไว้ข้างสคริปต์
import matplotlib
matplotlib.use("Agg") # รันแบบไม่มีหน้าจอ ถ้ารันในเครื่องตัวเองลบบรรทัดนี้ได้
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
C1, C2, C3 = "#2a78d6", "#eb6834", "#1baf7a" # palette ของคลัง เปลี่ยนเป็นสีองค์กรได้
INK, SURFACE = "#0b0b0b", "#fcfcfb"
df = pd.read_csv("glyph-plot-sample.csv")
df["ราคา"] = pd.to_numeric(df["ราคา"], errors="coerce")
df["ความเร็ว"] = pd.to_numeric(df["ความเร็ว"], errors="coerce")
df["ความจุ"] = pd.to_numeric(df["ความจุ"], errors="coerce")
df["น้ำหนัก"] = pd.to_numeric(df["น้ำหนัก"], errors="coerce")
df["คะแนนรีวิว"] = pd.to_numeric(df["คะแนนรีวิว"], errors="coerce")
NOTE = "channel" # ← ค่าจาก Playground
fig, ax = plt.subplots(figsize=(7.6, 4.2), facecolor=SURFACE)
ax.set_facecolor(SURFACE)
dims = ["ราคา", "ความเร็ว", "ความจุ", "น้ำหนัก", "คะแนนรีวิว"]
norm = df[dims].apply(lambda c: (c - c.min()) / (c.max() - c.min())) # ★ สเกลเดียวกัน
cols = 4
for i, (_, r) in enumerate(norm.head(12).iterrows()):
cx, cy = (i % cols) * 2.2, -(i // cols) * 2.2
for j, v in enumerate(r):
a = j / len(dims) * 2 * np.pi
ax.plot([cx, cx + np.cos(a) * v], [cy, cy + np.sin(a) * v],
color=C1, linewidth=2.4) # ก้าน = หนึ่งมิติ
ax.add_patch(plt.Circle((cx, cy), 1.0, fill=False, edgecolor="#e2e0da"))
ax.text(cx, cy - 1.3, df["item"].iloc[i], ha="center", fontsize=8)
ax.set_aspect("equal"); ax.autoscale_view(); ax.axis("off")
ax.spines[["top", "right"]].set_visible(False) # ลดเส้นที่ไม่ได้ให้ข้อมูล
fig.tight_layout()
fig.savefig("glyph-plot.png", dpi=160)
print("เขียน glyph-plot.png แล้ว ·", len(df), "แถว")07ลองเล่นเพื่อเข้าใจ
ต้องเรียนรู้วิธีอ่านก่อนใช้ — คนอ่านต้องจำได้ว่าก้านไหนคือตัวแปรไหน
ดูข้อมูลเป็นตาราง (12 แถว)
| รายการ | ราคา | ความเร็ว | ความจุ | น้ำหนัก | คะแนนรีวิว |
|---|---|---|---|---|---|
| รุ่น A | 167 | 48.5 | 17.6 | 30.9 | 3.17 |
| รุ่น B | 301 | 55.7 | 30.4 | 20.0 | 4.09 |
| รุ่น C | 393 | 76.1 | 43.6 | 17.2 | 4.14 |
| รุ่น D | 195 | 38.2 | 21.9 | 29.5 | 3.20 |
| รุ่น E | 304 | 57.4 | 35.1 | 23.3 | 3.82 |
| รุ่น F | 432 | 67.9 | 38.5 | 15.4 | 4.47 |
| รุ่น G | 186 | 42.8 | 18.5 | 30.0 | 3.04 |
| รุ่น H | 302 | 49.3 | 24.1 | 25.9 | 3.67 |
| รุ่น I | 396 | 77.5 | 44.1 | 18.2 | 4.41 |
| รุ่น J | 173 | 39.0 | 19.7 | 27.5 | 3.50 |
| รุ่น K | 308 | 60.0 | 34.2 | 22.1 | 3.82 |
| รุ่น L | 420 | 79.1 | 46.4 | 19.7 | 4.27 |
ลองแล้วจะเห็นอะไร
- สังเกตอะไร: สังเกตว่าความยาวของก้านสะดุดตากว่าความต่างของมุม — ตัวแปรที่จับคู่กับความยาวจึงดูสำคัญกว่าโดยที่ไม่มีใครตั้งใจ
ข้อควรระวัง
- ★ จับคู่ตัวแปรกับช่องทางโดยไม่คิด ทำให้ตัวแปรที่อยู่ในช่องทางที่อ่อนไหวมากดูสำคัญกว่าโดยไม่ตั้งใจ
- ใช้เกินเจ็ดมิติจนสัญลักษณ์อ่านไม่ออก
- ไม่ปรับทุกตัวแปรเป็นสเกลเดียวกัน
- ไม่ใส่สัญลักษณ์อ้างอิง ทำให้ไม่มีอะไรให้เทียบ
เมื่อไหร่ไม่ควรใช้กราฟนี้
- ต้องอ่านค่าของแต่ละมิติ→ใช้แทน: heatmap-matrix หรือ tableplot
- มีรายการมากกว่า 60 รายการ→ใช้แทน: parallel-coordinates หรือ embedding-projection
- มีรายการน้อยกว่า 4 รายการ→ใช้แทน: radar-chart หรือ grouped-bar