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

กราฟกล่องซ้อนชั้นLetter-value Plot

แสดงหางที่ box plot ยุบเหลือแค่จุด

5
เฉพาะทางควรรู้ก่อน · อ่าน box plot และเข้าใจควอนไทล์
ลองเล่น

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

Letter-value plot ขยาย box plot ด้วยการซ้อนกล่องหลายชั้น แต่ละชั้นแทนควอนไทล์ที่ลึกลงไปครึ่งหนึ่งเรื่อย ๆ เหตุผลคือเมื่อข้อมูลมีเป็นหมื่นแถว ควอนไทล์ที่ลึกยังประมาณได้แม่น การยุบทุกอย่างนอกหนวดให้เป็นจุดผิดปกติจึงทิ้งข้อมูลไปมาก

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

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

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

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

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

ตัวอย่างคลาสสิก · Hofmann, Wickham และ Kafadar เสนอ letter-value plot ในปี 2017

ทีมวิจัยชี้ว่า box plot แสดงจุดผิดปกติมากเกินจริงเมื่อข้อมูลใหญ่ เพราะเกณฑ์ 1.5 IQR ถูกปรับมาสำหรับข้อมูลขนาดเล็ก พวกเขาเสนอให้แสดงควอนไทล์ลึกเพิ่มตามจำนวนข้อมูลที่มี ซึ่งเป็นคำตอบที่มีฐานทางสถิติแทนการปรับเกณฑ์ตามใจ

Hofmann, Wickham & Kafadar · Letter-value plots (JCGS)

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

Box plot ถูกออกแบบในยุคที่ข้อมูลมีไม่กี่สิบแถว เกณฑ์ที่ว่าอะไรเกิน 1.5 เท่าของ IQR คือค่าผิดปกติจึงสมเหตุสมผลในบริบทนั้น

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

Letter-value plot แก้ด้วยการซ้อนกล่องเพิ่มเข้าไป กล่องในสุดคือครึ่งกลางเหมือนเดิม กล่องถัดออกมาคือ 75% ตรงกลาง แล้ว 87.5% ไล่ไปเรื่อย ๆ

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

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

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

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

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

คอลัมน์ทำหน้าที่ชนิดเข้ารหัสด้วยจำนวนค่าที่เหมาะหมายเหตุ
groupกลุ่มหมวดหมู่x1–8 กลุ่มเหมือน box plot
valueค่าที่วัดได้ตัวเลขต่อเนื่องyต่อเนื่อง★ ต้องมีข้อมูลมาก อย่างน้อยหลักพันต่อกลุ่ม จึงจะคุ้มกับการใช้กราฟนี้

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

  1. ตรวจว่าข้อมูลมากพอที่ควอนไทล์ลึกจะมีความหมาย
  2. กำหนดจำนวนชั้นตามขนาดข้อมูล
  3. ตัดค่าว่างออก

ค่าที่หายไป — ตัดค่าว่างและรายงานจำนวน เพราะจำนวนชั้นที่เหมาะสมขึ้นกับขนาดข้อมูล

สเกลของแกน — linear หรือ log ก็ได้ และ log มักเหมาะเมื่อหางยาวมาก

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

ต่ำกว่า 200 แถวต่อกลุ่ม ชั้นนอกจะมาจากข้อมูลไม่กี่จุดและไม่น่าเชื่อถือ — ใช้ box plot แทน

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

group,value

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

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

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

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

  • ไม่บอกรูปร่างของช่วงกลางละเอียดเท่า violin plot
  • ต้องอธิบายวิธีอ่านก่อนเสมอเพราะคนส่วนใหญ่ไม่รู้จัก

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

  1. ดูกล่องในสุดซึ่งคือครึ่งกลางเหมือน box plot
  2. ดูว่ากล่องชั้นนอกแผ่ออกไปเร็วแค่ไหน
  3. ดูจุดที่เหลือนอกกล่องทุกชั้น

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

  • หางของการกระจายหนาแค่ไหน
  • กลุ่มไหนมีค่าสุดโต่งมากกว่า

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

  • ใช้กับข้อมูลน้อยจนชั้นนอกมาจากไม่กี่จุด
  • ไม่อธิบายว่าแต่ละชั้นหมายถึงอะไร

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

ผู้ชมที่เหมาะนักวิเคราะห์ที่ทำงานกับข้อมูลขนาดใหญ่และสนใจหาง
เวลาที่ผู้ชมต้องใช้ต้องเรียนรู้ก่อน
ขนาดเล็กสุดที่ยังอ่านได้380×280 px
รายงานเชิงวิเคราะห์
สำรวจข้อมูลด้วยตัวเอง
สิ่งพิมพ์
สไลด์ผู้บริหารต้องอธิบายก่อนและซับซ้อนกว่า box plot มาก
สื่อสารกับคนทั่วไปแทบไม่มีใครนอกวงการสถิติรู้จักกราฟนี้

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

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

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

<กลุ่ม> มีหางขวาหนากว่ากลุ่มอื่นชัดเจน จากการแผ่ของชั้นนอก

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

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

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

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

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

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

sns.boxenplot(data=df, x="group", y="value", ax=ax, color="#9ec5f4", linewidth=0.8)
counts = df.groupby("group").size()
ax.set_xticklabels([f"{k}\n(n={v})" for k, v in counts.items()])
ax.set_ylabel("ค่าที่วัดได้")
ax.set_title("แต่ละชั้นคือควอนไทล์ที่ลึกลงไปครึ่งหนึ่ง", loc="left", fontsize=10)

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

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

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

ข้อมูลตัวอย่าง · 400 แถว · seed 101● คำนวณใหม่ในเบราว์เซอร์ทันทีที่ปรับค่า
ชั้นนอกคือหางของการกระจาย
สาขา Aสาขา Bสาขา Cสาขา D
40.050.060.070.080.090.0สาขา Aสาขา Bสาขา Cสาขา Dสาขา A · มัธยฐาน 57.5 · IQR 54.4–59.6 · n=100สาขา B · มัธยฐาน 66.2 · IQR 62.8–69.9 · n=100สาขา C · มัธยฐาน 61.7 · IQR 60.1–63.8 · n=100สาขา D · มัธยฐาน 73.9 · IQR 69.6–77.3 · n=100
กลุ่มที่มัธยฐานสูงสุดสาขา D
กลุ่มที่กระจายมากสุดสาขา D
จำนวนกลุ่ม4
ดูข้อมูลเป็นตาราง (4 แถว)
boxen plot 4 กลุ่ม
กลุ่มnต่ำสุดQ1มัธยฐานQ3สูงสุด
สาขา A10049.954.457.559.667.1
สาขา B10055.962.866.269.976.6
สาขา C10055.660.161.763.868.1
สาขา D10062.669.673.977.384.9

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

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

ข้อควรระวัง

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

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

  • ข้อมูลน้อยกว่า 200 แถวต่อกลุ่มใช้แทน: box-plot หรือ strip-plot
  • สนใจรูปร่างของช่วงกลางใช้แทน: violin-plot
  • ผู้อ่านไม่คุ้นกับสถิติใช้แทน: box-plot

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

เทคนิคถัดไป · กราฟเมฆฝน