01ภาพรวมของกราฟนี้
Hypothetical outcome plot แสดงผลลัพธ์ที่เป็นไปได้ทีละแบบสลับกันไป แทนที่จะสรุปเป็นแถบ ทำให้ผู้ชมที่ไม่เข้าใจสถิติรับรู้ความไม่แน่นอนได้ถูกต้องกว่าแถบความเชื่อมั่น แลกกับการที่ต้องเป็นสื่อเคลื่อนไหวและอ่านค่าที่แม่นไม่ได้
เปรียบเทียบให้เห็นภาพ
เหมือนดูคนทอยลูกเต๋าหลายครั้งแล้วเข้าใจว่าผลไม่แน่นอน ซึ่งเข้าใจง่ายกว่าการอ่านตารางความน่าจะเป็น
ใช้ที่ไหนบ้าง — สื่อสารความเสี่ยงกับสาธารณะ แสดงผลการเลือกตั้งที่ยังไม่แน่นอน หรืออธิบายพยากรณ์ให้ผู้ไม่มีพื้นฐานสถิติ
สร้างอย่างไร
- ขั้นที่ 1สุ่มผลลัพธ์จากการกระจายของแบบจำลอง
- ขั้นที่ 2แสดงทีละผลลัพธ์ด้วยจังหวะประมาณสี่ร้อยมิลลิวินาที
- ขั้นที่ 3เก็บร่องรอยของผลก่อนหน้าไว้จาง ๆ
- ขั้นที่ 4ให้ผู้ใช้หยุดและเลื่อนดูทีละเฟรมได้
ตัวอย่างคลาสสิก · งานวิจัยของ Hullman และคณะเรื่องการรับรู้ความไม่แน่นอน
Jessica Hullman และเพื่อนร่วมงานทดสอบว่าผู้คนประเมินความไม่แน่นอนได้แม่นแค่ไหนจากภาพแบบต่าง ๆ แล้วพบว่าผู้ที่ดูผลลัพธ์สมมติที่สลับไปมาประเมินได้ดีกว่าผู้ที่ดูแถบความเชื่อมั่น ซึ่งชี้ว่าการสรุปทางสถิติที่ดูสะอาดอาจสื่อสารได้แย่กว่าการแสดงความผันผวนตรง ๆ
02อธิบายภาษาคนเข้าใจง่าย ๆ
งานวิจัยด้านการรับรู้พบเรื่องที่น่าตกใจ คือคนส่วนใหญ่ตีความแถบความเชื่อมั่นผิด หลายคนเข้าใจว่าเส้นกลางคือคำตอบและแถบคือส่วนตกแต่ง
ปัญหาคือแถบเป็นการสรุปทางสถิติที่ต้องเรียนมาก่อนจึงจะอ่านถูก ซึ่งผู้ชมส่วนใหญ่ไม่ได้เรียน
Hypothetical outcome plot เลือกวิธีตรงข้าม คือไม่สรุปเลย แต่แสดงผลลัพธ์ที่เป็นไปได้ทีละแบบสลับกันไป ผู้ชมจึงเห็นด้วยตาว่าผลมันเด้งไปมาแค่ไหน
ข้อดีที่วัดได้จริงคือผู้ชมที่ไม่มีพื้นฐานสถิติประเมินความไม่แน่นอนได้แม่นกว่าเมื่อดูภาพแบบนี้ เทียบกับการดูแถบความเชื่อมั่น
ราคาที่จ่ายอย่างแรกคือมันต้องเป็นสื่อเคลื่อนไหว จึงใช้ในสิ่งพิมพ์หรือสไลด์แบบนิ่งไม่ได้เลย
อย่างที่สองคืออ่านค่าที่แม่นไม่ได้ ถ้าผู้อ่านต้องการตัวเลขไปคำนวณต่อ ต้องมีแถบหรือตารางควบคู่ไปด้วยเสมอ
03ข้อมูลที่ต้องใช้
คอลัมน์ที่ต้องเตรียม
| คอลัมน์ | ทำหน้าที่ | ชนิด | เข้ารหัสด้วย | จำนวนค่าที่เหมาะ | หมายเหตุ |
|---|---|---|---|---|---|
date | ลำดับหรือเวลา | มีลำดับ | x | 5–100 จุด | แกนที่ผลลัพธ์กระจายอยู่ |
value | ค่าที่สุ่มได้ | ตัวเลขต่อเนื่อง | y | ต่อเนื่อง | แต่ละเฟรมคือหนึ่งผลลัพธ์ที่เป็นไปได้ |
lowไม่บังคับ | ขอบล่างอ้างอิง | ช่วงค่า | y | ใช้กำหนดการสุ่ม | ไม่ได้วาดเป็นเส้น |
highไม่บังคับ | ขอบบนอ้างอิง | ช่วงค่า | y | ใช้กำหนดการสุ่ม | ไม่ได้วาดเป็นเส้น |
ต้องเตรียมข้อมูลอย่างไรก่อนวาด
- สุ่มผลลัพธ์จากการกระจายที่แบบจำลองให้
- ★ ล็อกค่าเริ่มต้นของการสุ่มเพื่อให้ทุกคนเห็นลำดับเดียวกัน
- เลือกจังหวะการเปลี่ยนเฟรมที่ตาตามทัน
ค่าที่หายไป — ถ้าสุ่มผลลัพธ์ไม่ได้ในบางจุด ต้องเว้นในทุกเฟรมเหมือนกัน
สเกลของแกน — ★ แกนค่าต้องคงที่ทุกเฟรม ไม่อย่างนั้นการเด้งที่เห็นจะมาจากแกนไม่ใช่จากข้อมูล
กราฟจะเริ่มพังเมื่อไร
เฟรมเปลี่ยนเร็วกว่า 250 มิลลิวินาที ตาตามไม่ทัน
หน้าตาไฟล์ที่ต้องเตรียม
date,value,low,high,kind
2025-01-01,100.9,97.7,104.1,ข้อมูลจริง
2025-01-31,102.3,99.1,105.5,ข้อมูลจริง
…04อ่านแล้วเห็นอะไร
สิ่งที่เห็นได้จากภาพ
- ขนาดของความผันผวนที่รู้สึกได้ทันที
- ผลลัพธ์สุดขั้วที่เป็นไปได้แต่ไม่บ่อย
- ความแตกต่างของความไม่แน่นอนระหว่างช่วง
สิ่งที่กราฟนี้ตอบไม่ได้
- ★ ค่าที่แม่นยำหรือช่วงความเชื่อมั่นที่ระบุเป็นตัวเลข
- ความน่าจะเป็นที่แน่นอนของผลลัพธ์แต่ละแบบ
อ่านตามลำดับนี้
- ดูหลายเฟรมแล้วสังเกตว่าเส้นเด้งไปมาแค่ไหน
- สังเกตว่าบริเวณไหนเด้งมากและบริเวณไหนนิ่ง
- หยุดเฟรมเพื่อดูผลลัพธ์แบบหนึ่ง ๆ
คำถามที่ตอบได้
- ผลมันเด้งได้แค่ไหน
- ผลลัพธ์ที่แย่ที่สุดหน้าตาเป็นอย่างไร
- เราแน่ใจแค่ไหนโดยไม่ต้องอ่านตัวเลข
สัญญาณว่ามีอะไรผิด
- แกนค่าเปลี่ยนตามเฟรม
- เฟรมเปลี่ยนเร็วเกินจนตาตามไม่ทัน
- ไม่มีแถบหรือตารางควบคู่สำหรับคนที่ต้องการตัวเลข
05เหมาะกับการนำเสนอแบบไหน
ทำอย่างไรให้คนอ่านได้ข้อสรุปโดยไม่ต้องบรรยาย
- ★ เขียนกำกับว่าแต่ละเฟรมคือหนึ่งผลลัพธ์ที่เป็นไปได้ ไม่ใช่ข้อมูลจริง
- ให้ปุ่มหยุดและเลื่อนทีละเฟรม
- ใส่ตารางหรือแถบควบคู่สำหรับคนที่ต้องการตัวเลข
รูปแบบชื่อกราฟที่ควรใช้
ผลลัพธ์ที่เป็นไปได้ของ <สิ่งที่พยากรณ์> แสดงทีละแบบ
06เอาไปใช้ต่อ
โค้ดทุกชิ้นอ่านไฟล์ hop-plot-sample.csv ชุดเดียวกับที่ Playground ใช้ และตัวเลขในโค้ดเปลี่ยนตามค่าที่คุณปรับด้านล่าง
# ติดตั้ง: pip install "matplotlib==3.10.*" "pandas==2.*"
# ดาวน์โหลด hop-plot-sample.csv จากหน้านี้ แล้ววางไว้ข้างสคริปต์
import matplotlib
matplotlib.use("Agg") # รันแบบไม่มีหน้าจอ ถ้ารันในเครื่องตัวเองลบบรรทัดนี้ได้
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
from matplotlib.animation import FuncAnimation
C1, C2, C3 = "#2a78d6", "#eb6834", "#1baf7a" # palette ของคลัง เปลี่ยนเป็นสีองค์กรได้
INK, SURFACE = "#0b0b0b", "#fcfcfb"
df = pd.read_csv("hop-plot-sample.csv")
df["value"] = pd.to_numeric(df["value"], errors="coerce")
df["low"] = pd.to_numeric(df["low"], errors="coerce")
df["high"] = pd.to_numeric(df["high"], errors="coerce")
FRAME = 0 # ← ค่าจาก Playground
fig, ax = plt.subplots(figsize=(7.6, 4.2), facecolor=SURFACE)
ax.set_facecolor(SURFACE)
d = df.sort_values("date").reset_index(drop=True)
sd = (d["high"] - d["low"]) / 3.92 # ประมาณ SD จากช่วง 95%
rng = np.random.default_rng(42) # ★ ล็อกเพื่อให้ทุกคนเห็นเหมือนกัน
lo, hi = d["low"].min(), d["high"].max()
(line,) = ax.plot(d.index, d["value"], color=C1, linewidth=2.4)
ax.set_ylim(lo, hi) # ★ แกนคงที่ทุกเฟรม
def frame(_):
line.set_ydata(d["value"] + rng.normal(0, sd))
return (line,)
anim = FuncAnimation(fig, frame, frames=40, interval=400, blit=True)
anim.save("hop.gif", writer="pillow") # แสดงเป็นภาพเคลื่อนไหวเท่านั้น
ax.spines[["top", "right"]].set_visible(False) # ลดเส้นที่ไม่ได้ให้ข้อมูล
fig.tight_layout()
fig.savefig("hop-plot.png", dpi=160)
print("เขียน hop-plot.png แล้ว ·", len(df), "แถว")07ลองเล่นเพื่อเข้าใจ
ต้องเลื่อนดูหลายชุดถึงจะเข้าใจความไม่แน่นอน — ดูชุดเดียวแล้วเชื่อว่าเป็นคำตอบคือการอ่านผิด
ดูข้อมูลเป็นตาราง (24 แถว)
| ลำดับ | ค่ากลาง | ชุดนี้ |
|---|---|---|
| 1 | 101 | 109 |
| 2 | 102 | 100 |
| 3 | 101 | 93.4 |
| 4 | 103 | 107 |
| 5 | 104 | 110 |
| 6 | 103 | 97.5 |
| 7 | 103 | 97.7 |
| 8 | 101 | 108 |
| 9 | 99.7 | 103 |
| 10 | 99.6 | 91.7 |
| 11 | 102 | 101 |
| 12 | 103 | 111 |
| 13 | 103 | 102 |
| 14 | 106 | 97.9 |
| 15 | 109 | 112 |
| 16 | 112 | 119 |
| 17 | 113 | 108 |
| 18 | 116 | 110 |
| 19 | 118 | 124 |
| 20 | 119 | 124 |
| 21 | 123 | 116 |
| 22 | 125 | 122 |
| 23 | 127 | 135 |
| 24 | 126 | 126 |
ลองแล้วจะเห็นอะไร
- ผลลัพธ์ที่: เลื่อนไปมาหลายเฟรมแล้วสังเกตว่าเส้นเด้งแค่ไหน — ความรู้สึกนั้นคือสิ่งที่แถบความเชื่อมั่นสื่อไม่ได้
ข้อควรระวัง
- ★ ปล่อยให้แกนค่าเปลี่ยนตามเฟรม ทำให้การเด้งที่เห็นมาจากแกนไม่ใช่จากข้อมูล
- เปลี่ยนเฟรมเร็วเกินจนผู้ชมตามไม่ทัน
- ใช้เป็นภาพเดียวโดยไม่มีแถบหรือตารางควบคู่ ทำให้คนที่ต้องการตัวเลขใช้ไม่ได้
- ไม่บอกว่าแต่ละเฟรมคือผลลัพธ์สมมติ ทำให้ผู้ชมคิดว่าเป็นข้อมูลจริงที่เปลี่ยนไป
เมื่อไหร่ไม่ควรใช้กราฟนี้
- ต้องพิมพ์หรือใส่สไลด์แบบนิ่ง→ใช้แทน: fan-chart หรือ confidence-band
- ผู้อ่านต้องการตัวเลขไปคำนวณต่อ→ใช้แทน: error-bars
- ผู้อ่านเป็นนักสถิติอยู่แล้ว→ใช้แทน: confidence-band ที่อ่านค่าได้ตรง