01ภาพรวมของกราฟนี้
Rug plot วาดขีดสั้น ๆ หนึ่งขีดต่อหนึ่งจุดข้อมูลไว้ที่ขอบแกน หน้าที่หลักของมันไม่ใช่การเป็นกราฟเดี่ยว แต่เป็นชั้นเสริมที่บอกผู้อ่านว่าเส้นหรือรูปที่เห็นด้านบนมาจากข้อมูลจริงกี่จุดและอยู่ตรงไหน
เปรียบเทียบให้เห็นภาพ
เหมือนรอยเท้าบนหาดทรายใต้ภาพวาดของชายหาด รอยเท้าบอกว่ามีคนเดินผ่านตรงไหนจริง ๆ ส่วนภาพวาดเป็นการตีความ
ใช้ที่ไหนบ้าง — วางใต้กราฟความหนาแน่น วางที่ขอบของ scatter plot หรือใช้เดี่ยวเมื่อข้อมูลมีน้อยมาก
สร้างอย่างไร
- ขั้นที่ 1วาดขีดหนึ่งขีดต่อหนึ่งจุดข้อมูล
- ขั้นที่ 2วางไว้ที่ขอบของกราฟหลัก
- ขั้นที่ 3ใช้ความโปร่งใสเมื่อขีดเริ่มทับกัน
- ขั้นที่ 4ทำเครื่องหมายค่าสรุปสำคัญ
ตัวอย่างคลาสสิก · Rug plot เป็นชั้นเสริมมาตรฐานในหนังสือ Visualizing Data ของ Cleveland
Cleveland แนะนำให้แสดงตำแหน่งข้อมูลจริงควบคู่กับเส้นที่ประมาณขึ้นเสมอ เพราะผู้อ่านต้องรู้ว่าส่วนไหนของเส้นมีหลักฐานรองรับหนาแน่นและส่วนไหนเป็นการคาดเดาจากข้อมูลไม่กี่จุด
02อธิบายภาษาคนเข้าใจง่าย ๆ
กราฟความหนาแน่นให้เส้นเรียบที่สวยและน่าเชื่อถือ แต่มันไม่ได้บอกว่าเส้นนั้นมาจากข้อมูล 20 จุดหรือ 20,000 จุด ซึ่งเป็นความต่างที่สำคัญมาก
Rug plot แก้ด้วยการวาดขีดหนึ่งขีดต่อหนึ่งจุดข้อมูลไว้ที่ฐาน ผู้อ่านจึงเห็นด้วยตาตัวเองว่าข้อมูลจริงกระจุกตรงไหน และมีช่วงไหนที่เส้นด้านบนเป็นการประมาณล้วน ๆ
เพราะมันกินพื้นที่น้อยมาก จึงเพิ่มลงไปในกราฟอื่นได้แทบทุกชนิดโดยไม่รบกวน นี่คือเหตุผลที่มันมักปรากฏเป็นชั้นเสริมมากกว่าเป็นกราฟเดี่ยว
เมื่อใช้เดี่ยว ๆ มันเหมาะกับข้อมูลที่น้อยมากจริง ๆ เช่น 10-30 จุด ซึ่งการวาดฮิสโทแกรมจะเป็นการสรุปที่เกินความจำเป็น
ข้อจำกัดคือขีดที่ค่าเท่ากันจะทับกันสนิท ทำให้บริเวณที่หนาแน่นดูเหมือนมีข้อมูลน้อยกว่าความจริง ทางแก้คือใช้ความโปร่งใสหรือเปลี่ยนไปใช้ strip plot
03ข้อมูลที่ต้องใช้
คอลัมน์ที่ต้องเตรียม
| คอลัมน์ | ทำหน้าที่ | ชนิด | เข้ารหัสด้วย | จำนวนค่าที่เหมาะ | หมายเหตุ |
|---|---|---|---|---|---|
value | ค่าที่วัดได้ | ตัวเลขต่อเนื่อง | x | ต่อเนื่อง | ข้อมูลดิบ หนึ่งขีดต่อหนึ่งแถว |
ต้องเตรียมข้อมูลอย่างไรก่อนวาด
- ตัดค่าว่างออก
- ตัดสินใจว่าจะวางเดี่ยวหรือเป็นชั้นเสริม
- ปรับความโปร่งใสตามจำนวนข้อมูล
ค่าที่หายไป — ตัดค่าว่างและรายงานจำนวน เพราะจำนวนขีดคือสิ่งที่ผู้อ่านนับ
สเกลของแกน — ใช้สเกลเดียวกับกราฟหลักที่มันเสริมอยู่เสมอ
กราฟจะเริ่มพังเมื่อไร
เกิน 500 จุด ขีดจะทับกันจนกลายเป็นแถบทึบ — ใช้ความโปร่งใสหรือเปลี่ยนไปใช้ histogram
หน้าตาไฟล์ที่ต้องเตรียม
value
…04อ่านแล้วเห็นอะไร
สิ่งที่เห็นได้จากภาพ
- ตำแหน่งของข้อมูลจริงทุกจุด
- ช่วงที่ไม่มีข้อมูลเลย
- จำนวนข้อมูลโดยประมาณ
สิ่งที่กราฟนี้ตอบไม่ได้
- ไม่บอกความหนาแน่นที่แม่นยำเมื่อขีดทับกัน
- ไม่ให้ค่าสรุปใด ๆ
อ่านตามลำดับนี้
- ดูว่าขีดกระจุกตรงไหน
- หาช่วงที่ไม่มีขีดเลย
- กะจำนวนขีดทั้งหมด
คำถามที่ตอบได้
- ข้อมูลจริงอยู่ตรงไหนบ้าง
- มีช่วงไหนที่เส้นด้านบนเป็นการประมาณล้วน ๆ
สัญญาณว่ามีอะไรผิด
- ขีดทับกันจนกลายเป็นแถบทึบ
- ใช้เดี่ยวกับข้อมูลจำนวนมาก
05เหมาะกับการนำเสนอแบบไหน
ทำอย่างไรให้คนอ่านได้ข้อสรุปโดยไม่ต้องบรรยาย
- เขียนจำนวนขีดทั้งหมด
- ทำเครื่องหมายค่าสรุปเช่นควอไทล์ด้วยเส้นที่สูงกว่าขีดปกติ
รูปแบบชื่อกราฟที่ควรใช้
ข้อมูลจริง <จำนวน> จุด กระจุกอยู่ระหว่าง <ช่วง>
06เอาไปใช้ต่อ
โค้ดทุกชิ้นอ่านไฟล์ rug-plot-sample.csv ชุดเดียวกับที่ Playground ใช้ และตัวเลขในโค้ดเปลี่ยนตามค่าที่คุณปรับด้านล่าง
# ติดตั้ง: pip install "matplotlib==3.10.*" "pandas==2.*"
# ดาวน์โหลด rug-plot-sample.csv จากหน้านี้ แล้ววางไว้ข้างสคริปต์
import matplotlib
matplotlib.use("Agg") # รันแบบไม่มีหน้าจอ ถ้ารันในเครื่องตัวเองลบบรรทัดนี้ได้
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
C1, C2, C3 = "#2a78d6", "#eb6834", "#1baf7a" # palette ของคลัง เปลี่ยนเป็นสีองค์กรได้
INK, SURFACE = "#0b0b0b", "#fcfcfb"
df = pd.read_csv("rug-plot-sample.csv")
df["value"] = pd.to_numeric(df["value"], errors="coerce")
NOTE = "gaps" # ← ค่าจาก Playground
fig, ax = plt.subplots(figsize=(7.6, 4.2), facecolor=SURFACE)
ax.set_facecolor(SURFACE)
v = df["value"].dropna()
ax.plot(v, np.zeros_like(v), "|", color=C1, markersize=22, alpha=0.45, markeredgewidth=1.2)
for label, q in [("Q1", 0.25), ("มัธยฐาน", 0.5), ("Q3", 0.75)]:
val = v.quantile(q)
ax.plot([val, val], [-0.02, 0.02], color=INK, linewidth=1.6) # ค่าสรุปใช้ขีดที่สูงกว่า
ax.annotate(f"{label}\n{val:,.1f}", (val, 0.025), ha="center", fontsize=8)
ax.set_ylim(-0.06, 0.06); ax.set_yticks([]); ax.set_xlabel("ค่าที่วัดได้")
ax.spines[["top", "right"]].set_visible(False) # ลดเส้นที่ไม่ได้ให้ข้อมูล
fig.tight_layout()
fig.savefig("rug-plot.png", dpi=160)
print("เขียน rug-plot.png แล้ว ·", len(df), "แถว")07ลองเล่นเพื่อเข้าใจ
ขีดที่ทับกันสนิททำให้บริเวณหนาแน่นดูมีข้อมูลน้อยกว่าความจริง
ดูข้อมูลเป็นตาราง (5 แถว)
| สถิติ | ค่า |
|---|---|
| ต่ำสุด | 50.2 |
| Q1 | 59.3 |
| มัธยฐาน | 62.0 |
| Q3 | 65.6 |
| สูงสุด | 71.7 |
ลองแล้วจะเห็นอะไร
- สังเกตอะไร: มองหาช่วงที่ไม่มีขีดเลย ถ้าเอากราฟความหนาแน่นมาวางทับ เส้นจะยังลากผ่านช่วงนั้นทั้งที่ไม่มีข้อมูลสักจุด
ข้อควรระวัง
- ใช้เดี่ยวกับข้อมูลจำนวนมากจนขีดกลายเป็นแถบทึบ
- ไม่ใช้ความโปร่งใส ทำให้ประเมินความหนาแน่นผิด
- วางไว้ไกลจากกราฟหลักจนผู้อ่านไม่เชื่อมโยงสองอย่างเข้าด้วยกัน
เมื่อไหร่ไม่ควรใช้กราฟนี้
- มีข้อมูลมากกว่า 500 จุด→ใช้แทน: histogram หรือ density-plot
- ต้องการค่าสรุป→ใช้แทน: box-plot
- ต้องเทียบหลายกลุ่ม→ใช้แทน: strip-plot