01ภาพรวมของกราฟนี้
100% stacked bar ยืดทุกแท่งให้สูงเท่ากัน แล้วแบ่งเป็นสัดส่วนของแต่ละหมวดย่อย ผลคือเทียบ "องค์ประกอบ" ข้ามกลุ่มได้ง่ายมาก เพราะทุกแท่งมีมาตรวัดเดียวกัน แต่ต้องยอมรับว่าข้อมูลขนาดของกลุ่มหายไปจากภาพทั้งหมด
เปรียบเทียบให้เห็นภาพ
เหมือนถ่ายรูปพายของแต่ละบ้านแล้วย่อ-ขยายให้ทุกถาดใหญ่เท่ากัน เราจึงเทียบได้ว่าบ้านไหนแบ่งชิ้นให้ใครมากกว่ากัน แต่จะไม่รู้เลยว่าพายของบ้านไหนใหญ่กว่ากันจริง ๆ
ใช้ที่ไหนบ้าง — เทียบสัดส่วนช่องทางการขายระหว่างภูมิภาคที่มีขนาดต่างกันมาก เทียบส่วนผสมของประชากรระหว่างจังหวัด หรือดูว่าสัดส่วนผู้ใช้แต่ละแพลตฟอร์มเปลี่ยนไปอย่างไรตามปี
สร้างอย่างไร
- ขั้นที่ 1คำนวณสัดส่วนของแต่ละหมวดย่อยภายในกลุ่ม
- ขั้นที่ 2ยืดทุกแท่งให้เป็น 100%
- ขั้นที่ 3คงลำดับการซ้อนให้เหมือนกัน
- ขั้นที่ 4เขียนขนาดของกลุ่มกำกับไว้เพราะภาพซ่อนไว้
ตัวอย่างคลาสสิก · องค์ประกอบพลังงานของแต่ละประเทศ
ประเทศใหญ่กับประเทศเล็กมีการใช้พลังงานรวมต่างกันหลายร้อยเท่า การเทียบ "สัดส่วนพลังงานหมุนเวียน" จึงต้องยืดทุกแท่งให้เท่ากันก่อน มิฉะนั้นประเทศเล็กจะกลายเป็นเส้นบาง ๆ ที่อ่านอะไรไม่ได้เลย งานของ Our World in Data จึงคู่กราฟนี้กับตัวเลขปริมาณจริงเสมอ
02อธิบายภาษาคนเข้าใจง่าย ๆ
ปัญหาของแท่งซ้อนธรรมดาคือ ถ้ากลุ่มหนึ่งใหญ่กว่าอีกกลุ่มมาก แท่งของกลุ่มใหญ่จะสูงลิ่วจนเราเทียบองค์ประกอบภายในไม่ได้เลย เช่น เทียบสัดส่วนช่องทางขายของกรุงเทพกับจังหวัดเล็ก ๆ
ทางแก้คือเลิกสนใจขนาด แล้วเปลี่ยนทุกแท่งให้สูงเท่ากันที่ 100% แต่ละช่วงสีจึงกลายเป็นเปอร์เซ็นต์ของกลุ่มตัวเอง ทีนี้เราเทียบได้ตรง ๆ ว่าสัดส่วนของช่องทางแอปในกรุงเทพสูงกว่าหรือต่ำกว่าจังหวัดอื่น
ราคาที่ต้องจ่ายคือข้อมูลขนาดหายไปหมด จังหวัดที่มียอดขาย 10 ล้านกับจังหวัดที่มียอด 10,000 บาท จะมีแท่งสูงเท่ากันเป๊ะ ซึ่งอาจนำไปสู่ข้อสรุปที่ผิดอย่างร้ายแรงถ้าผู้อ่านไม่รู้ข้อนี้
เพราะเหตุนี้ กราฟชนิดนี้ต้องมีการเขียนขนาดของแต่ละกลุ่มกำกับไว้เสมอ ไม่ว่าจะเป็นตัวเลขข้างชื่อกลุ่ม หรือความกว้างของแท่งที่แปรตามขนาด ซึ่งจะกลายเป็น mosaic plot
ข้อดีที่หลายคนมองข้ามคือ ชั้นล่างสุดและชั้นบนสุดอ่านได้แม่นทั้งคู่ เพราะทั้งคู่ติดขอบที่ตรงกันทุกแท่ง ดังนั้นควรวางหมวดที่สำคัญที่สุดสองหมวดไว้ล่างสุดและบนสุด ส่วนหมวดที่ไม่สำคัญไว้ตรงกลาง
03ข้อมูลที่ต้องใช้
คอลัมน์ที่ต้องเตรียม
| คอลัมน์ | ทำหน้าที่ | ชนิด | เข้ารหัสด้วย | จำนวนค่าที่เหมาะ | หมายเหตุ |
|---|---|---|---|---|---|
category | กลุ่มที่จะเทียบสัดส่วน | หมวดหมู่ | x | 2–12 กลุ่ม | ขนาดของกลุ่มจะหายไปจากภาพ ต้องเขียนกำกับ |
group | หมวดย่อย | หมวดหมู่ | color | 2–5 หมวด | วางหมวดสำคัญไว้ล่างสุดและบนสุด เพราะสองตำแหน่งนี้อ่านแม่นที่สุด |
value | ปริมาณดิบ | ตัวเลขต่อเนื่อง | y | บวกเท่านั้น | ใส่ค่าดิบ ไม่ต้องคำนวณเปอร์เซ็นต์มาก่อน ให้กราฟคำนวณให้ |
ต้องเตรียมข้อมูลอย่างไรก่อนวาด
- ตรวจว่าทุกกลุ่มมีข้อมูลครบทุกหมวดย่อย
- บันทึกยอดรวมของแต่ละกลุ่มไว้เขียนกำกับ
- วางหมวดที่สำคัญที่สุดไว้ล่างสุด
ค่าที่หายไป — ถ้าบางกลุ่มเก็บข้อมูลไม่ครบ สัดส่วนที่คำนวณได้จะผิดทั้งกลุ่ม ต้องตัดกลุ่มนั้นออกและระบุ ไม่ใช่เติมศูนย์
สเกลของแกน — แกนเป็น 0–100% เสมอ ไม่มีทางเลือกอื่น
กราฟจะเริ่มพังเมื่อไร
เกิน 6 หมวดย่อย ช่วงกลางจะบางจนอ่านไม่ออก และเกิน 12 กลุ่มแท่งจะบางเกินไป
หน้าตาไฟล์ที่ต้องเตรียม
category,group,value
…04อ่านแล้วเห็นอะไร
สิ่งที่เห็นได้จากภาพ
- กลุ่มไหนมีสัดส่วนของหมวดหนึ่งสูงผิดจากกลุ่มอื่น
- องค์ประกอบโดยรวมเหมือนกันทุกกลุ่มหรือต่างกันชัดเจน
- แนวโน้มของสัดส่วนเมื่อเรียงกลุ่มตามลำดับที่มีความหมาย เช่น ปี
- หมวดที่ครองสัดส่วนใหญ่ในทุกกลุ่ม
สิ่งที่กราฟนี้ตอบไม่ได้
- ★ ไม่บอกขนาดของกลุ่มเลย — สองแท่งที่หน้าตาเหมือนกันอาจมาจากข้อมูล 10 แถวกับ 10,000 แถว
- ไม่บอกว่าสัดส่วนที่เปลี่ยนมาจากตัวเศษเพิ่มหรือตัวส่วนลด
- เทียบหมวดที่อยู่ตรงกลางข้ามกลุ่มได้ยาก
อ่านตามลำดับนี้
- ดูชั้นล่างสุดก่อน เพราะเริ่มที่ 0% ทุกแท่งจึงเทียบได้แม่น
- ดูชั้นบนสุดต่อ เพราะจบที่ 100% ทุกแท่งเช่นกัน
- ตรวจขนาดของกลุ่มจากตัวเลขที่เขียนกำกับ
- ระวังไม่สรุปเรื่องปริมาณจากภาพนี้
คำถามที่ตอบได้
- กลุ่มไหนพึ่งพาช่องทางนี้มากที่สุดเมื่อคิดเป็นสัดส่วน
- องค์ประกอบเปลี่ยนไปอย่างไรเมื่อเวลาผ่านไป
- มีกลุ่มไหนที่โครงสร้างต่างจากกลุ่มอื่นอย่างชัดเจน
สัญญาณว่ามีอะไรผิด
- ไม่มีตัวเลขขนาดของกลุ่มกำกับไว้เลย
- กลุ่มที่มีข้อมูลน้อยมากถูกวางเคียงกับกลุ่มใหญ่โดยไม่มีคำเตือน
- ช่วงกลางบางจนมองไม่เห็นแต่ยังใส่ไว้
05เหมาะกับการนำเสนอแบบไหน
ทำอย่างไรให้คนอ่านได้ข้อสรุปโดยไม่ต้องบรรยาย
- เขียนยอดรวม n ของแต่ละกลุ่มไว้ข้างชื่อกลุ่มเสมอ — ข้อนี้เป็นข้อบังคับไม่ใช่ทางเลือก
- ติดเปอร์เซ็นต์ในช่วงที่กว้างพอ
- ถ้าเรียงกลุ่มตามเวลา ให้ลากเส้นเชื่อมขอบของชั้นเดียวกันเพื่อให้เห็นแนวโน้ม
รูปแบบชื่อกราฟที่ควรใช้
สัดส่วนของ <หมวด> ใน <กลุ่ม> สูงถึง <เปอร์เซ็นต์> เทียบกับ <เปอร์เซ็นต์> ใน <กลุ่มอื่น>
06เอาไปใช้ต่อ
โค้ดทุกชิ้นอ่านไฟล์ percent-stacked-bar-sample.csv ชุดเดียวกับที่ Playground ใช้ และตัวเลขในโค้ดเปลี่ยนตามค่าที่คุณปรับด้านล่าง
# ติดตั้ง: pip install "matplotlib==3.10.*" "pandas==2.*"
# ดาวน์โหลด percent-stacked-bar-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("percent-stacked-bar-sample.csv")
df["value"] = pd.to_numeric(df["value"], errors="coerce")
VIEW = "percent" # ← ค่าจาก Playground
fig, ax = plt.subplots(figsize=(7.6, 4.2), facecolor=SURFACE)
ax.set_facecolor(SURFACE)
pivot = df.pivot_table(index="category", columns="group", values="value", aggfunc="sum").fillna(0)
totals = pivot.sum(axis=1)
share = pivot.div(totals, axis=0) * 100
bottom = None
for i, col in enumerate(share.columns):
ax.bar(share.index, share[col], bottom=bottom, label=col,
color=[C1, C2, C3][i % 3], edgecolor=SURFACE, linewidth=1.6)
bottom = share[col] if bottom is None else bottom + share[col]
# เขียนขนาดของกลุ่มกำกับเสมอ เพราะภาพซ่อนข้อมูลนี้ไว้
ax.set_xticks(range(len(totals)))
ax.set_xticklabels([f"{k}\n(n={v:,.0f})" for k, v in totals.items()], fontsize=9)
ax.set_ylim(0, 100); ax.set_ylabel("สัดส่วน (%)"); ax.legend(frameon=False, ncols=3)
ax.spines[["top", "right"]].set_visible(False) # ลดเส้นที่ไม่ได้ให้ข้อมูล
fig.tight_layout()
fig.savefig("percent-stacked-bar.png", dpi=160)
print("เขียน percent-stacked-bar.png แล้ว ·", len(df), "แถว")07ลองเล่นเพื่อเข้าใจ
ดูข้อมูลเป็นตาราง (6 แถว)
| หมวด | หน้าร้าน | เว็บไซต์ | แอป | รวม |
|---|---|---|---|---|
| เหนือ | 91.0 | 93.0 | 94.0 | 278 |
| อีสาน | 120 | 84.0 | 154 | 358 |
| กลาง | 88.0 | 73.0 | 130 | 291 |
| ตะวันออก | 82.0 | 47.0 | 134 | 263 |
| ตะวันตก | 92.0 | 70.0 | 136 | 298 |
| ใต้ | 86.0 | 94.0 | 129 | 309 |
ลองแล้วจะเห็นอะไร
- มุมมอง: สังเกตว่าทุกแท่งสูงเท่ากันหมด ขนาดจริงของแต่ละภูมิภาคหายไปจากภาพโดยสิ้นเชิง — เปิดตารางเพื่อดูว่าซ่อนอะไรไว้
ข้อควรระวัง
- ★ ไม่เขียนขนาดของแต่ละกลุ่มกำกับ ทำให้คนอ่านคิดว่าทุกกลุ่มใหญ่เท่ากัน
- ใช้กับกลุ่มที่มีข้อมูลน้อยมาก เช่น 8 คน ซึ่งสัดส่วนจะแกว่งแรงจนไม่มีความหมาย
- สรุปว่าปริมาณเพิ่มขึ้นทั้งที่กราฟบอกได้แค่ว่าสัดส่วนเพิ่มขึ้น ซึ่งอาจเกิดจากตัวอื่นลดลงก็ได้
- วางหมวดที่สำคัญที่สุดไว้ตรงกลาง ซึ่งเป็นตำแหน่งที่อ่านยากที่สุด
- ใส่หมวดย่อยเกิน 5 หมวดจนช่วงกลางบางเกินกว่าจะเห็น
เมื่อไหร่ไม่ควรใช้กราฟนี้
- ขนาดของกลุ่มเป็นประเด็นสำคัญ→ใช้แทน: stacked-bar หรือ mosaic-plot ที่ความกว้างบอกขนาด
- มีเพียงสองหมวดย่อย→ใช้แทน: bar-chart ของสัดส่วนหมวดเดียว ซึ่งอ่านง่ายกว่ามาก
- เป็นสเกลความเห็นที่มีลำดับ เช่น พอใจมาก–ไม่พอใจ→ใช้แทน: sentiment-diverging ที่จัดกึ่งกลางที่ความเห็นกลาง