เทคนิคที่ 024 · PYTHON / JAVASCRIPT

กราฟฮอไรซันHorizon Chart

ใส่ 20 อนุกรมในพื้นที่ของ 3 อนุกรม

5
เฉพาะทางควรรู้ก่อน · อ่านกราฟพื้นที่เป็น และเข้าใจการแลกความแม่นกับความหนาแน่นของข้อมูล
ลองเล่น

01ภาพรวมของกราฟนี้

Horizon chart บีบความสูงของกราฟพื้นที่ด้วยการตัดค่าที่เกินแล้วพับกลับมาซ้อนเป็นชั้นที่เข้มขึ้น ผลคือใส่อนุกรมได้หลายสิบเส้นในหน้าเดียว แลกกับการที่ผู้อ่านต้องเรียนรู้วิธีอ่านก่อน

เปรียบเทียบให้เห็นภาพ

เหมือนแผนที่ระดับความสูงที่ใช้สีเข้มขึ้นแทนความสูงที่มากขึ้น แทนที่จะวาดภูเขาให้สูงจริงจนเกินกระดาษ

ใช้ที่ไหนบ้าง — ติดตามตัวชี้วัดหลายสิบตัวพร้อมกัน เซิร์ฟเวอร์หลายเครื่อง เซ็นเซอร์หลายจุด หรือหุ้นหลายตัวในหน้าเดียว

สร้างอย่างไร

  1. ขั้นที่ 1กำหนดจำนวนชั้นที่จะพับ ปกติ 3 ชั้น
  2. ขั้นที่ 2ตัดค่าที่เกินแต่ละชั้นแล้วพับกลับ
  3. ขั้นที่ 3ให้ชั้นที่สูงกว่าใช้สีเข้มขึ้น
  4. ขั้นที่ 4ใส่คำอธิบายวิธีอ่านไว้ข้างกราฟ

ตัวอย่างคลาสสิก · Horizon graph ของ Panopticon และงานวิจัยของ Heer, Kong และ Agrawala

ทีมวิจัยทดลองกับผู้ใช้จริงเพื่อหาว่ากราฟฮอไรซันบีบได้แค่ไหนก่อนที่ความแม่นจะตก ผลคือการพับ 2-3 ชั้นให้ประสิทธิภาพดีที่สุด และการบีบให้เตี้ยลงมากยังอ่านได้ดีกว่าที่คาด ซึ่งกลายเป็นข้อแนะนำมาตรฐานจนถึงวันนี้

Heer, Kong & Agrawala · Sizing the Horizon (CHI 2009)

02อธิบายภาษาคนเข้าใจง่าย ๆ

ถ้าต้องดูแนวโน้มของเซิร์ฟเวอร์ 30 เครื่องพร้อมกัน การวางกราฟเส้น 30 อันเรียงกันจะกินพื้นที่มหาศาลและต้องเลื่อนหน้าไปมาจนเทียบกันไม่ได้

Horizon chart บีบความสูงด้วยกลอุบายง่าย ๆ คือแบ่งช่วงค่าเป็นชั้น ๆ แล้วแทนที่จะวาดชั้นที่สองต่อขึ้นไปในแนวตั้ง ก็พับมันลงมาทับชั้นแรกโดยใช้สีเข้มขึ้น

ผลคือความสูงของแต่ละแถวเหลือแค่หนึ่งในสามหรือหนึ่งในสี่ แต่ข้อมูลยังอยู่ครบ เพียงแค่ย้ายจากการเข้ารหัสด้วยความสูงไปเป็นการเข้ารหัสด้วยความเข้มของสีบางส่วน

ราคาที่จ่ายชัดเจนคือผู้อ่านต้องเรียนรู้ก่อน เพราะถ้าไม่รู้กติกา สีเข้มจะดูเหมือนแค่การตกแต่ง ต้องมีคำอธิบายวิธีอ่านอยู่ข้างกราฟเสมอ

ข้อดีที่ได้กลับมาคุ้มเมื่อจำนวนอนุกรมเยอะจริง ๆ เพราะทุกแถวอยู่ในหน้าจอเดียวกัน ตาจึงเทียบรูปแบบข้ามแถวได้ ซึ่งเป็นสิ่งที่การเลื่อนหน้าทำลายไปหมด

03ข้อมูลที่ต้องใช้

รูปทรงของข้อมูลตารางแบบยาว (หนึ่งแถวหนึ่งสังเกต)
จำนวนมิติที่เข้ารหัสได้3 มิติ
จำนวนแถวที่เหมาะ10–30 แถว × 50–200 จุดเวลาขั้นต่ำ 60 แถว
เส้นฐานศูนย์ต้องเริ่มที่ศูนย์การพับชั้นนิยามจากระยะเหนือเส้นฐาน ถ้าเส้นฐานไม่ใช่ศูนย์ ชั้นจะไม่มีความหมาย

คอลัมน์ที่ต้องเตรียม

คอลัมน์ทำหน้าที่ชนิดเข้ารหัสด้วยจำนวนค่าที่เหมาะหมายเหตุ
dateเวลาเวลาx30–500 จุดทุกอนุกรมต้องมีจุดเวลาตรงกัน
seriesอนุกรมหมวดหมู่row5–40 แถวจุดแข็งของกราฟนี้คือรองรับแถวได้เยอะ
valueค่าตัวเลขต่อเนื่องyต่อเนื่องควรใช้สเกลร่วมกันทุกแถวเพื่อให้เทียบข้ามแถวได้

ต้องเตรียมข้อมูลอย่างไรก่อนวาด

  1. จัดให้ทุกอนุกรมมีจุดเวลาตรงกัน
  2. เลือกสเกลร่วมหรือสเกลรายแถวและระบุให้ชัด
  3. กำหนดจำนวนชั้นที่จะพับ

ค่าที่หายไป — ช่วงที่ขาดข้อมูลต้องเว้นว่างให้เห็น ห้ามเติมศูนย์เพราะศูนย์จะกลายเป็นชั้นอ่อนสุดที่ดูเหมือนมีข้อมูล

สเกลของแกน — linear และควรใช้สเกลร่วมทุกแถวเมื่อต้องการเทียบข้ามแถว

กราฟจะเริ่มพังเมื่อไร

น้อยกว่า 5 แถวไม่คุ้มกับความยากในการอ่าน — ใช้ small-multiples แทน

หน้าตาไฟล์ที่ต้องเตรียม

date,series,value

04อ่านแล้วเห็นอะไร

สิ่งที่เห็นได้จากภาพ

  • แถวไหนที่มีช่วงค่าสูงบ่อย จากปริมาณสีเข้ม
  • ช่วงเวลาที่หลายแถวสูงพร้อมกัน ซึ่งมักเป็นเหตุการณ์ร่วม
  • รูปแบบที่ซ้ำกันข้ามแถว

สิ่งที่กราฟนี้ตอบไม่ได้

  • อ่านค่าที่แม่นยำไม่ได้ เพราะความสูงถูกตัดและพับ
  • ผู้ที่ไม่รู้กติกาจะอ่านผิดทั้งหมด

อ่านตามลำดับนี้

  1. อ่านคำอธิบายจำนวนชั้นและช่วงค่าของแต่ละชั้นก่อน
  2. ดูปริมาณและความเข้มของสีในแต่ละแถว
  3. มองแนวตั้งเพื่อหาช่วงเวลาที่หลายแถวเข้มพร้อมกัน

คำถามที่ตอบได้

  • มีช่วงเวลาไหนที่ทุกอย่างพุ่งพร้อมกัน
  • แถวไหนที่ผิดปกติเมื่อเทียบกับแถวอื่น

สัญญาณว่ามีอะไรผิด

  • ไม่มีคำอธิบายวิธีอ่าน
  • แต่ละแถวใช้สเกลของตัวเองแต่ให้ผู้อ่านเทียบข้ามแถว

05เหมาะกับการนำเสนอแบบไหน

ผู้ชมที่เหมาะทีมที่ดูข้อมูลชุดนี้ทุกวันและได้เรียนรู้วิธีอ่านแล้ว
เวลาที่ผู้ชมต้องใช้ต้องเรียนรู้ก่อน
ขนาดเล็กสุดที่ยังอ่านได้520×240 px
dashboard ที่อัปเดตตลอด
รายงานเชิงวิเคราะห์
สำรวจข้อมูลด้วยตัวเอง
สไลด์ผู้บริหารต้องอธิบายวิธีอ่านก่อน ซึ่งไม่มีเวลาในสไลด์
สื่อสารกับคนทั่วไปผู้อ่านทั่วไปไม่รู้กติกาการพับชั้น

ทำอย่างไรให้คนอ่านได้ข้อสรุปโดยไม่ต้องบรรยาย

  1. ใส่คำอธิบายจำนวนชั้นและช่วงค่าไว้ข้างกราฟเสมอ
  2. เขียนค่าสูงสุดของแต่ละแถวไว้ท้ายแถว

รูปแบบชื่อกราฟที่ควรใช้

<จำนวน> อนุกรมในหน้าเดียว · สีเข้มขึ้นหมายถึงค่าที่สูงขึ้นอีกชั้น

06เอาไปใช้ต่อ

โค้ดทุกชิ้นอ่านไฟล์ horizon-chart-sample.csv ชุดเดียวกับที่ Playground ใช้ และตัวเลขในโค้ดเปลี่ยนตามค่าที่คุณปรับด้านล่าง

# ติดตั้ง: pip install "matplotlib==3.10.*" "pandas==2.*"
# ดาวน์โหลด horizon-chart-sample.csv จากหน้านี้ แล้ววางไว้ข้างสคริปต์
import matplotlib
matplotlib.use("Agg")   # รันแบบไม่มีหน้าจอ ถ้ารันในเครื่องตัวเองลบบรรทัดนี้ได้
import matplotlib.pyplot as plt
import pandas as pd

C1, C2, C3 = "#2a78d6", "#eb6834", "#1baf7a"   # palette ของคลัง เปลี่ยนเป็นสีองค์กรได้
INK, SURFACE = "#0b0b0b", "#fcfcfb"

df = pd.read_csv("horizon-chart-sample.csv")
df["value"] = pd.to_numeric(df["value"], errors="coerce")
NOTE = "bands"   # ← ค่าจาก Playground

fig, ax = plt.subplots(figsize=(7.6, 4.2), facecolor=SURFACE)
ax.set_facecolor(SURFACE)

df["date"] = pd.to_datetime(df["date"])
names = list(df["series"].unique()); bands = 3
vmax = df["value"].max(); step = vmax / bands
fig.clf(); fig.set_size_inches(7.6, 0.9 * len(names) + 0.5)
for i, name in enumerate(names):
    g = df[df["series"] == name].sort_values("date")
    a = fig.add_subplot(len(names), 1, i + 1)
    for b in range(bands):
        lo = b * step
        a.fill_between(g["date"], 0, (g["value"] - lo).clip(0, step),   # ตัดแล้วพับกลับ
                       color=["#9ec5f4", "#3987e5", "#184f95"][b])
    a.set_ylim(0, step); a.axis("off")
    a.text(0, 0.5, name, transform=a.transAxes, ha="right", fontsize=9)

ax.spines[["top", "right"]].set_visible(False)   # ลดเส้นที่ไม่ได้ให้ข้อมูล
fig.tight_layout()
fig.savefig("horizon-chart.png", dpi=160)
print("เขียน horizon-chart.png แล้ว ·", len(df), "แถว")

ติดตั้ง: pip install "matplotlib==3.10.*" "pandas==2.*" · ทดสอบกับเวอร์ชัน 3.10

07ลองเล่นเพื่อเข้าใจ

ข้อมูลตัวอย่าง · 26 แถว · seed 29● คำนวณใหม่ในเบราว์เซอร์ทันทีที่ปรับค่า
สีเข้มขึ้น = ค่าที่สูงขึ้นอีกชั้น
หน้าร้านหน้าร้านเว็บไซต์เว็บไซต์แอปแอป

horizon chart ต้องอธิบายวิธีอ่านก่อนใช้ — สีเข้มขึ้นหมายถึงค่าที่พับทับกันอีกชั้น

จำนวนอนุกรม3
จำนวนชั้นสี3
ค่าสูงสุดรวม86.8
ดูข้อมูลเป็นตาราง (3 แถว)
horizon chart 3 อนุกรม 3 ชั้นสี
อนุกรมต่ำสุดสูงสุดเฉลี่ย
หน้าร้าน56.071.362.2
เว็บไซต์53.486.871.8
แอป31.684.456.5

ลองแล้วจะเห็นอะไร

  • สังเกตอะไร: ลองอ่านแถวที่มีสีเข้มสุดโดยไม่ดูตาราง แล้วเช็ค จะเห็นว่ากติกาการพับต้องอธิบายก่อนเสมอ ไม่มีใครเดาถูกเอง

ข้อควรระวัง

  1. ไม่ใส่คำอธิบายวิธีอ่าน ทำให้ผู้อ่านตีความสีเข้มเป็นแค่การตกแต่ง
  2. ใช้กับอนุกรมน้อย ๆ ซึ่งไม่คุ้มกับความยากในการอ่าน
  3. ให้แต่ละแถวใช้สเกลของตัวเองแล้วให้ผู้อ่านเทียบข้ามแถว
  4. ใช้จำนวนชั้นมากเกินไปจนแยกความเข้มไม่ออก

เมื่อไหร่ไม่ควรใช้กราฟนี้

  • มีอนุกรมน้อยกว่า 5 อนุกรมใช้แทน: small-multiples หรือ multi-line-chart
  • ผู้อ่านไม่เคยเห็นกราฟชนิดนี้มาก่อนใช้แทน: small-multiples
  • ต้องอ่านค่าที่แม่นยำใช้แทน: line-chart

กราฟที่เกี่ยวข้อง

เทคนิคถัดไป · ปฏิทินความร้อน