01ภาพรวมของกราฟนี้
Stacked bar chart วางหมวดย่อยซ้อนกันในแท่งเดียว ความสูงรวมคือยอดรวมของกลุ่ม ส่วนแต่ละช่วงสีคือส่วนประกอบ จุดแข็งคือตอบสองคำถามในภาพเดียว แต่แลกมาด้วยข้อจำกัดว่าเฉพาะชั้นล่างสุดเท่านั้นที่เริ่มจากเส้นฐานเดียวกัน จึงเทียบได้แม่นแค่ชั้นเดียว
เปรียบเทียบให้เห็นภาพ
เหมือนกองหนังสือหลายเล่มซ้อนกัน เรารู้ความสูงรวมของกองทันที และรู้ว่าเล่มล่างสุดหนาแค่ไหน แต่ถ้าจะเทียบความหนาของเล่มกลางระหว่างสองกอง จะยากเพราะมันลอยอยู่คนละระดับ
ใช้ที่ไหนบ้าง — ยอดขายรวมรายเดือนที่แยกตามสินค้า งบประมาณรวมรายหน่วยงานที่แยกตามหมวดรายจ่าย หรือจำนวนผู้ใช้รวมที่แยกตามแพลตฟอร์ม
สร้างอย่างไร
- ขั้นที่ 1เลือกตัวแปรกลุ่มและตัวแปรหมวดย่อย
- ขั้นที่ 2กำหนดลำดับการซ้อนให้คงที่
- ขั้นที่ 3วางหมวดที่สำคัญที่สุดไว้ชั้นล่างสุด
- ขั้นที่ 4ใส่ legend และเว้นช่องว่างบาง ๆ ระหว่างชั้น
ตัวอย่างคลาสสิก · งบประมาณแผ่นดินที่แยกตามกระทรวง
กราฟงบประมาณเป็นการใช้งานที่ตรงกับจุดแข็งของแท่งซ้อนที่สุด เพราะผู้อ่านอยากรู้ทั้งวงเงินรวมของแต่ละปีและสัดส่วนที่แต่ละกระทรวงได้ไปพร้อมกัน และเพราะเงินบวกกันได้จริง การซ้อนจึงมีความหมายทางคณิตศาสตร์
02อธิบายภาษาคนเข้าใจง่าย ๆ
กราฟแท่งซ้อนเกิดจากคำถามสองข้อที่มักมาคู่กัน คือ "รวมแล้วเท่าไร" และ "ประกอบด้วยอะไรบ้าง" แทนที่จะวาดสองกราฟ เราเอาส่วนประกอบมาต่อกันเป็นแท่งเดียว ความสูงรวมจึงตอบข้อแรก และช่วงสีตอบข้อสอง
ข้อจำกัดที่คนมักไม่รู้คือ ในบรรดาชั้นทั้งหมด มีเพียงชั้นล่างสุดเท่านั้นที่เริ่มจากเส้นฐานเดียวกันทุกแท่ง ชั้นที่สองขึ้นไปจะลอยอยู่คนละระดับตามความสูงของชั้นล่าง การเทียบชั้นบน ๆ ข้ามแท่งจึงทำได้ยากมาก
ผลที่ตามมาคือ เราควรเอาหมวดที่สำคัญที่สุดหรือที่อยากให้คนเทียบมากที่สุดไว้ชั้นล่างสุดเสมอ นี่เป็นการตัดสินใจเชิงบรรณาธิการที่กระทบสิ่งที่คนอ่านเห็น ไม่ใช่แค่เรื่องความสวยงาม
จำนวนชั้นควรอยู่ที่ 3-5 ชั้น ถ้ามากกว่านี้ชั้นบาง ๆ จะบีบจนมองไม่เห็นและสีจะเยอะเกินกว่าที่คนตาบอดสีจะแยกได้ ทางแก้คือรวมหมวดเล็กเป็น "อื่น ๆ" ไว้ชั้นบนสุด
ถ้าคำถามจริง ๆ คือสัดส่วนไม่ใช่ยอดรวม ให้เปลี่ยนไปใช้แบบ 100% ซ้อน ซึ่งทุกแท่งสูงเท่ากันและอ่านสัดส่วนได้ตรง ภาพจำคือ แท่งซ้อนธรรมดาตอบเรื่องยอดรวม ส่วนแท่งซ้อน 100% ตอบเรื่องสัดส่วน
03ข้อมูลที่ต้องใช้
คอลัมน์ที่ต้องเตรียม
| คอลัมน์ | ทำหน้าที่ | ชนิด | เข้ารหัสด้วย | จำนวนค่าที่เหมาะ | หมายเหตุ |
|---|---|---|---|---|---|
category | กลุ่มหลัก | หมวดหมู่ | x | 2–10 กลุ่ม | แต่ละกลุ่มได้หนึ่งแท่ง |
group | หมวดย่อยที่ซ้อนกัน | หมวดหมู่ | color | 2–5 ชั้น | เกิน 5 ชั้นจะบางจนอ่านไม่ออก ให้รวมเป็น "อื่น ๆ" |
value | ปริมาณ | ตัวเลขต่อเนื่อง | y | บวกเท่านั้น | ค่าติดลบซ้อนกันไม่ได้ ถ้ามีต้องใช้ diverging-bar แทน |
ต้องเตรียมข้อมูลอย่างไรก่อนวาด
- ตรวจว่าค่าทุกตัวเป็นบวก
- กำหนดลำดับการซ้อนให้คงที่ทุกแท่ง โดยวางหมวดสำคัญไว้ล่างสุด
- รวมหมวดที่คิดเป็นน้อยกว่า 3% ของยอดรวมเป็น "อื่น ๆ"
ค่าที่หายไป — หมวดที่ไม่มีข้อมูลในบางกลุ่มให้ใส่ศูนย์ได้ต่อเมื่อศูนย์เป็นค่าที่ถูกต้องจริง ๆ ถ้าแค่ไม่ได้เก็บข้อมูล ต้องทำเครื่องหมายแยกไว้ ไม่อย่างนั้นยอดรวมจะต่ำกว่าความจริง
สเกลของแกน — linear เริ่มที่ศูนย์เท่านั้น การซ้อนอาศัยสมบัติว่าผลรวมของความยาวเท่ากับความยาวรวม ซึ่ง log ทำลายทิ้ง
กราฟจะเริ่มพังเมื่อไร
เกิน 6 ชั้น ชั้นบาง ๆ จะหายไปในภาพ — รวมเป็น "อื่น ๆ" หรือเปลี่ยนไปใช้ small-multiples
หน้าตาไฟล์ที่ต้องเตรียม
category,group,value
…04อ่านแล้วเห็นอะไร
สิ่งที่เห็นได้จากภาพ
- กลุ่มไหนมียอดรวมสูงสุด
- หมวดย่อยไหนเป็นตัวขับยอดรวมของแต่ละกลุ่ม
- สัดส่วนขององค์ประกอบเปลี่ยนไปอย่างไรข้ามกลุ่ม
- หมวดที่มีอยู่ทุกกลุ่มกับหมวดที่โผล่เฉพาะบางกลุ่ม
สิ่งที่กราฟนี้ตอบไม่ได้
- เทียบชั้นกลางและชั้นบนข้ามแท่งได้ยากมาก เพราะไม่ได้เริ่มจากเส้นฐานเดียวกัน
- ไม่บอกสัดส่วนโดยตรง ต้องคำนวณเอง — ถ้าต้องการสัดส่วนให้ใช้ percent-stacked-bar
- ไม่รองรับค่าติดลบ
อ่านตามลำดับนี้
- ดูความสูงรวมของแต่ละแท่งก่อน
- ดูชั้นล่างสุดซึ่งเป็นชั้นเดียวที่เทียบข้ามแท่งได้แม่น
- ดูว่าชั้นไหนหนาขึ้นหรือบางลงเมื่อเปลี่ยนกลุ่ม
- ใช้ตารางข้อมูลยืนยันตัวเลขของชั้นบน ๆ
คำถามที่ตอบได้
- ยอดรวมของแต่ละกลุ่มเป็นเท่าไร
- ชั้นล่างสุดของกลุ่มไหนใหญ่ที่สุด
- อะไรทำให้กลุ่มนี้ยอดรวมสูงกว่ากลุ่มอื่น
สัญญาณว่ามีอะไรผิด
- ชั้นบาง ๆ จำนวนมากที่มองแทบไม่เห็น แปลว่ายังไม่ได้รวมเป็น "อื่น ๆ"
- ลำดับการซ้อนเปลี่ยนไปในแต่ละแท่ง
- มีค่าติดลบปนอยู่ ทำให้การซ้อนไม่มีความหมาย
05เหมาะกับการนำเสนอแบบไหน
ทำอย่างไรให้คนอ่านได้ข้อสรุปโดยไม่ต้องบรรยาย
- เขียนยอดรวมไว้เหนือแท่ง เพราะเป็นตัวเลขที่คนมองหาก่อน
- ติดป้ายชื่อหมวดลงในชั้นที่หนาพอ แทนการพึ่ง legend อย่างเดียว
- เว้นช่องว่าง 2px สีเดียวกับพื้นระหว่างชั้น เพื่อให้ขอบชั้นชัด
รูปแบบชื่อกราฟที่ควรใช้
<กลุ่ม> มียอดรวมสูงสุดที่ <ค่า> โดยมาจาก <หมวดย่อย> เป็นหลัก
06เอาไปใช้ต่อ
โค้ดทุกชิ้นอ่านไฟล์ stacked-bar-sample.csv ชุดเดียวกับที่ Playground ใช้ และตัวเลขในโค้ดเปลี่ยนตามค่าที่คุณปรับด้านล่าง
# ติดตั้ง: pip install "matplotlib==3.10.*" "pandas==2.*"
# ดาวน์โหลด 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("stacked-bar-sample.csv")
df["value"] = pd.to_numeric(df["value"], errors="coerce")
VIEW = "stacked" # ← ค่าจาก 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)
bottom = None
for i, col in enumerate(pivot.columns):
ax.bar(pivot.index, pivot[col], bottom=bottom, label=col,
color=[C1, C2, C3][i % 3], edgecolor=SURFACE, linewidth=1.6) # เส้นขอบ = ช่องว่างระหว่างชั้น
bottom = pivot[col] if bottom is None else bottom + pivot[col]
for i, total in enumerate(pivot.sum(axis=1)):
ax.text(i, total * 1.02, f"{total:,.0f}", ha="center", fontsize=9)
ax.set_ylim(0, None); ax.legend(frameon=False, ncols=3)
ax.grid(axis="y", alpha=0.25); ax.set_axisbelow(True)
ax.spines[["top", "right"]].set_visible(False) # ลดเส้นที่ไม่ได้ให้ข้อมูล
fig.tight_layout()
fig.savefig("stacked-bar.png", dpi=160)
print("เขียน 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 |
ลองแล้วจะเห็นอะไร
- มุมมอง: ลองตามชั้นที่สองจากล่างข้ามทุกแท่งด้วยตา แล้วเปิดตารางเช็ค จะเห็นว่าสายตาประเมินชั้นที่ไม่ติดเส้นฐานได้แย่กว่าที่คิดมาก
ข้อควรระวัง
- พยายามให้คนเทียบชั้นที่ไม่ใช่ชั้นล่างสุดข้ามแท่ง ซึ่งสายตาทำไม่ได้แม่น
- ใส่ชั้นเกิน 5-6 ชั้น จนชั้นบาง ๆ หายไปและสีเกินเพดานที่คนตาบอดสีแยกได้
- ซ้อนค่าที่เป็นสัดส่วนหรืออัตรา ซึ่งบวกกันไม่ได้ทางคณิตศาสตร์
- สลับลำดับการซ้อนในแต่ละแท่ง ทำให้ตามชั้นเดิมไม่ได้
- ใส่ค่าติดลบปนกับค่าบวก ทำให้ความสูงรวมไม่ใช่ยอดรวมอีกต่อไป
เมื่อไหร่ไม่ควรใช้กราฟนี้
- คำถามคือสัดส่วนภายในกลุ่ม→ใช้แทน: percent-stacked-bar
- ต้องเทียบหมวดย่อยข้ามกลุ่มอย่างแม่นยำ→ใช้แทน: grouped-bar หรือ small-multiples
- มีค่าติดลบ→ใช้แทน: diverging-bar
- ข้อมูลเป็นอนุกรมเวลา→ใช้แทน: stacked-area