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

แถบไล่ระดับGradient Band

เลี่ยงขอบคมที่ทำให้ผู้อ่านคิดว่ามีเส้นแบ่ง

4
ขั้นสูงควรรู้ก่อน · เข้าใจว่าความน่าจะเป็นไม่มีขอบเขตคม
ลองเล่น

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

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

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

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

ใช้ที่ไหนบ้าง — พยากรณ์ที่ต้องเลี่ยงการตีความว่ามีขอบเขตแน่นอน การสื่อสารความเสี่ยงกับสาธารณะ หรือการแสดงการกระจายของค่าประมาณ

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

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

ตัวอย่างคลาสสิก · Density strip ในการสื่อสารความไม่แน่นอนทางสถิติ

Jackson เสนอ density strip ในปี 2008 โดยชี้ว่าแถบความเชื่อมั่นแบบมีขอบทำให้ผู้อ่านตีความว่าค่าในช่วงเป็นไปได้เท่ากันหมดและค่านอกช่วงเป็นไปไม่ได้ ซึ่งผิดทั้งสองข้อ การไล่ความเข้มตามความหนาแน่นจึงตรงกับสิ่งที่สถิติบอกมากกว่า

Wikipedia · Density estimation

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

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

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

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

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

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

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

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

รูปทรงของข้อมูลอนุกรมเวลา
จำนวนมิติที่เข้ารหัสได้3 มิติ
จำนวนแถวที่เหมาะ20–200 จุดเวลาขั้นต่ำ 8 แถว
เส้นฐานศูนย์เลือกได้สื่อระดับของค่า ไม่ใช่ปริมาณสะสม

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

คอลัมน์ทำหน้าที่ชนิดเข้ารหัสด้วยจำนวนค่าที่เหมาะหมายเหตุ
dateเวลาเวลาx10–300 จุดเรียงตามเวลา
valueค่ากลางตัวเลขต่อเนื่องyต่อเนื่องบริเวณที่เข้มที่สุด
lowขอบล่างอ้างอิงช่วงค่าopacityใช้กำหนดการไล่ระดับไม่ได้วาดเป็นเส้น
highขอบบนอ้างอิงช่วงค่าopacityใช้กำหนดการไล่ระดับไม่ได้วาดเป็นเส้น

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

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

ค่าที่หายไป — ช่วงที่ไม่มีข้อมูลต้องเว้นว่าง ซึ่งอ่านง่ายเพราะไม่มีสีเลย

สเกลของแกน — ความทึบแปรตามความหนาแน่นของความน่าจะเป็น และต้องอธิบายในคำอธิบายว่าเข้มแปลว่าอะไร

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

ซ้อนมากกว่า 2 แถบ ความเข้มจะบวกกันจนอ่านผิด

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

date,value,low,high,kind
2025-01-01,100.9,97.7,104.1,ข้อมูลจริง
2025-01-31,102.3,99.1,105.5,ข้อมูลจริง

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

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

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

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

  • ★ ช่วงที่ระดับความเชื่อมั่นใดระดับหนึ่ง เพราะไม่มีขอบให้อ่าน
  • ค่าที่แน่นอนของความน่าจะเป็นที่จุดใดจุดหนึ่ง

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

  1. มองหาบริเวณที่เข้มที่สุดซึ่งคือค่าที่น่าจะเป็นมากที่สุด
  2. ดูว่าสีจางออกไปกว้างแค่ไหน
  3. อ่านคำอธิบายว่าความเข้มแทนอะไร

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

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

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

  • ไม่อธิบายว่าความเข้มแทนอะไร
  • ใช้ชั้นน้อยเกินจนเห็นขอบเป็นขั้นบันได
  • ซ้อนหลายแถบจนความเข้มบวกกัน

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

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

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

  1. ★ อธิบายว่าความเข้มแทนความน่าจะเป็น
  2. ติดค่ากลางเป็นตัวเลขที่จุดสำคัญ
  3. เพิ่มเส้นค่ากลางบาง ๆ เพื่อให้มีหลักให้จับ

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

<ตัวชี้วัด> โดยความเข้มแทนความน่าจะเป็นของค่านั้น

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

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

# ติดตั้ง: pip install "matplotlib==3.10.*" "pandas==2.*"
# ดาวน์โหลด gradient-band-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("gradient-band-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")
NOTE = "edge"   # ← ค่าจาก Playground

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

d = df.sort_values("date")
LAYERS = 24                                         # ชั้นมากพอจนไม่เห็นขั้นบันได
for i in range(LAYERS):
    f = 1 - i / LAYERS
    ax.fill_between(d["date"],
                    d["value"] - (d["value"] - d["low"]) * f,
                    d["value"] + (d["high"] - d["value"]) * f,
                    color=C1, alpha=0.035, linewidth=0)
ax.plot(d["date"], d["value"], color=C1, linewidth=1.6)
ax.set_ylabel("ค่าที่คาด")
ax.set_title("ความเข้ม = ความน่าจะเป็นของค่านั้น", loc="left", fontsize=10)

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

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

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

ข้อมูลตัวอย่าง · 24 แถว · seed 401● คำนวณใหม่ในเบราว์เซอร์ทันทีที่ปรับค่า
ไม่มีขอบให้หา
ข้อมูลจริงพยากรณ์ช่วงความไม่แน่นอน
100120140160ก.พ. 68ต.ค. 68พ.ค. 69เริ่มพยากรณ์

ขอบของแถบไม่ใช่เส้นแบ่งระหว่าง "เป็นไปได้" กับ "เป็นไปไม่ได้" — ค่าที่อยู่นอกแถบยังเกิดขึ้นได้

ความกว้างช่วงล่าสุด54.4
ความกว้างช่วงแรก6.40
จุดพยากรณ์8
ดูข้อมูลเป็นตาราง (24 แถว)
fan chart 24 จุดเวลา
วันที่ค่ากลางขอบล่างขอบบนชนิด
1/1/256810197.7104ข้อมูลจริง
31/1/256810299.1106ข้อมูลจริง
2/3/256810197.8104ข้อมูลจริง
1/4/256810399.5106ข้อมูลจริง
1/5/2568104101107ข้อมูลจริง
31/5/2568103100106ข้อมูลจริง
30/6/256810399.6106ข้อมูลจริง
30/7/256810197.4104ข้อมูลจริง
29/8/256899.796.5103ข้อมูลจริง
28/9/256899.696.4103ข้อมูลจริง
28/10/256810298.6105ข้อมูลจริง
27/11/256810399.7106ข้อมูลจริง
27/12/256810399.8106ข้อมูลจริง
26/1/2569106103109ข้อมูลจริง
25/2/2569109106112ข้อมูลจริง
27/3/2569112109115ข้อมูลจริง
26/4/2569113110117พยากรณ์
26/5/2569116109122พยากรณ์
25/6/2569118108128พยากรณ์
25/7/2569119106133พยากรณ์
24/8/2569123106140พยากรณ์
23/9/2569125104145พยากรณ์
23/10/2569127103151พยากรณ์
22/11/256912698.8153พยากรณ์

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

  • สังเกตอะไร: เทียบกับหน้า confidence-band ที่ใช้ข้อมูลชุดเดียวกัน จะเห็นว่าที่นี่ไม่มีเส้นแบ่งให้ผู้อ่านเข้าใจผิดว่าข้างนอกเป็นไปไม่ได้

ข้อควรระวัง

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

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

  • ผู้อ่านต้องอ่านช่วงที่ระดับความเชื่อมั่นเฉพาะใช้แทน: confidence-band หรือ fan-chart
  • ต้องพิมพ์ขาวดำใช้แทน: confidence-band
  • ค่าประมาณแยกกันไม่ต่อเนื่องใช้แทน: error-bars

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

เทคนิคถัดไป · กราฟผลลัพธ์สมมติ