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

กราฟแท่งสองทางDiverging Bar Chart

ใครอยู่เหนือเส้นฐาน ใครอยู่ใต้ และห่างแค่ไหน

2
ต่อยอดโดยตรงควรรู้ก่อน · อ่านกราฟแท่งเป็น
ลองเล่น

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

Diverging bar chart ย้ายเส้นฐานจากขอบมาไว้กลางภาพ แท่งที่ค่าเป็นบวกยื่นไปทางหนึ่ง ค่าติดลบยื่นไปอีกทาง ทำให้ "ทิศทาง" กลายเป็นสิ่งที่เห็นก่อนขนาด ซึ่งตรงกับคำถามที่กราฟนี้ตอบพอดี คือใครดีขึ้นใครแย่ลง

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

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

ใช้ที่ไหนบ้าง — ส่วนต่างจากเป้าหมายรายสาขา การเปลี่ยนแปลงยอดขายเทียบปีก่อน กำไรขาดทุนรายผลิตภัณฑ์ หรือคะแนนความเห็นที่มีทั้งเห็นด้วยและไม่เห็นด้วย

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

  1. ขั้นที่ 1เลือกเส้นฐานที่มีความหมาย เช่น ศูนย์ ค่าเฉลี่ย หรือเป้าหมาย
  2. ขั้นที่ 2คำนวณส่วนต่างจากเส้นฐาน
  3. ขั้นที่ 3เรียงตามส่วนต่าง
  4. ขั้นที่ 4ใช้สีสองขั้วที่มีเทาเป็นจุดกลาง

ตัวอย่างคลาสสิก · พีระมิดประชากร — กราฟสองทางที่เก่าแก่ที่สุดที่ยังใช้อยู่

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

Our World in Data · Population pyramid

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

เวลาข้อมูลมีทั้งค่าบวกและค่าลบ กราฟแท่งธรรมดาจะอ่านยาก เพราะแท่งของค่าลบต้องห้อยลงจากเส้นฐานที่อยู่กลาง ๆ และคนอ่านต้องคอยดูเครื่องหมายกำกับ

กราฟแท่งสองทางแก้ปัญหานี้ด้วยการทำให้ "ทิศทาง" เป็นพระเอก แท่งที่ยื่นไปทางขวาคือดีขึ้น แท่งที่ยื่นไปทางซ้ายคือแย่ลง คนอ่านรู้คำตอบก่อนที่จะอ่านตัวเลขด้วยซ้ำ

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

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

สิ่งที่ต้องระวังคือ กราฟนี้ทำให้ความต่างเล็ก ๆ ดูใหญ่ เพราะแท่งสองฝั่งรวมกันเป็นระยะทางสองเท่า ถ้าค่าจริงต่างกันแค่ 1-2% แต่ภาพดูเหมือนคนละโลก ควรใส่สเกลให้ชัดหรือเปลี่ยนไปใช้กราฟอื่น

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

รูปทรงของข้อมูลตารางแบบยาว (หนึ่งแถวหนึ่งสังเกต)
จำนวนมิติที่เข้ารหัสได้2 มิติ
จำนวนแถวที่เหมาะ5–20 รายการขั้นต่ำ 3 แถว
เส้นฐานศูนย์ต้องเริ่มที่ศูนย์ทั้งกราฟนิยามจากเส้นฐาน ถ้าเส้นฐานไม่อยู่ตรงค่าที่ประกาศไว้ ภาพจะโกหกทั้งใบ

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

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

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

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

ค่าที่หายไป — รายการที่คำนวณส่วนต่างไม่ได้ต้องแยกออกและระบุ ห้ามถือว่าเป็นศูนย์ เพราะศูนย์แปลว่า "เท่ากับเส้นฐานพอดี" ซึ่งเป็นข้อมูลคนละอย่าง

สเกลของแกน — linear และควรให้สองฝั่งกว้างเท่ากันเพื่อไม่ให้ฝั่งใดดูใหญ่กว่าโดยผลของการจัดหน้า

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

ถ้าค่าทั้งหมดเป็นบวกหรือลบทางเดียว กราฟนี้เสียความหมาย ให้ใช้ horizontal-bar แทน

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

category,value

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

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

  • รายการไหนอยู่เหนือเส้นฐานและรายการไหนอยู่ใต้
  • สัดส่วนของรายการที่ดีขึ้นเทียบกับที่แย่ลง
  • รายการที่ห่างจากเส้นฐานมากที่สุดทั้งสองฝั่ง
  • ความสมมาตร — ถ้าฝั่งหนึ่งมีแท่งยาวกว่าอีกฝั่งชัดเจน

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

  • ไม่บอกค่าสัมบูรณ์ — รายการที่ส่วนต่าง +5 อาจมาจากฐาน 10 หรือฐาน 10,000 ก็ได้
  • ไม่บอกว่าส่วนต่างที่เห็นมีนัยสำคัญทางสถิติหรือไม่
  • ไม่บอกว่าเกิดอะไรขึ้นระหว่างทาง

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

  1. หาเส้นกลางก่อนและอ่านว่ามันคืออะไร
  2. ดูว่าฝั่งไหนมีแท่งมากกว่า
  3. ดูแท่งที่ยาวที่สุดของทั้งสองฝั่ง
  4. ตรวจว่าสเกลสองฝั่งเท่ากัน

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

  • มีกี่รายการที่ทำได้ตามเป้า
  • ใครแย่ลงมากที่สุด
  • ภาพรวมเอียงไปทางบวกหรือลบ

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

  • ไม่บอกว่าเส้นกลางคืออะไร
  • สเกลสองฝั่งไม่เท่ากัน ทำให้ฝั่งหนึ่งดูรุนแรงกว่า
  • ใช้สีที่ไม่ได้สื่อความตรงข้าม เช่น ฟ้ากับเขียว

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

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

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

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

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

<จำนวน> จาก <ทั้งหมด> รายการอยู่เหนือ <เส้นฐาน> โดย <รายการ> ห่างมากที่สุดที่ <ค่า>

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

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

# ติดตั้ง: pip install "matplotlib==3.10.*" "pandas==2.*"
# ดาวน์โหลด diverging-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("diverging-bar-sample.csv")
df["value"] = pd.to_numeric(df["value"], errors="coerce")
SORT = "value-desc"   # ← ค่าจาก Playground

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

d = df.sort_values("value")
colors = ["#2a78d6" if v < 0 else "#e34948" for v in d["value"]]   # สองขั้วที่รู้สึกตรงข้ามกัน
ax.barh(d["category"], d["value"], color=colors, height=0.72)
ax.axvline(0, color=INK, linewidth=1.4)
lim = d["value"].abs().max() * 1.15
ax.set_xlim(-lim, lim)                 # สองฝั่งกว้างเท่ากัน ไม่ให้ฝั่งใดดูรุนแรงกว่า
ax.set_xlabel("ส่วนต่างจากเป้าหมาย")
ax.grid(axis="x", alpha=0.25); ax.set_axisbelow(True)

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

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

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

ข้อมูลตัวอย่าง · 12 แถว · seed 11● คำนวณใหม่ในเบราว์เซอร์ทันทีที่ปรับค่า
ลำดับของแถว
ต่ำกว่าเส้นฐานสูงกว่าเส้นฐาน
ระยองนครปฐมพิษณุโลกอุดรธานีสุราษฎร์ธานีสงขลานครราชสีมาภูเก็ตชลบุรีเชียงใหม่ขอนแก่นกรุงเทพฯ-30.0-20.0-10.00.0010.020.030.0ระยอง · +20.1นครปฐม · +15.3พิษณุโลก · +10.0อุดรธานี · +5.00สุราษฎร์ธานี · +4.90สงขลา · -0.10นครราชสีมา · -1.30ภูเก็ต · -6.10ชลบุรี · -9.00เชียงใหม่ · -13.0ขอนแก่น · -14.3กรุงเทพฯ · -20.7
อยู่เหนือเส้นฐาน5 จาก 12
ห่างมากที่สุด20.7
ค่ากลาง-0.10
ดูข้อมูลเป็นตาราง (12 แถว)
กราฟแท่งสองทาง 12 หมวด มี 5 หมวดอยู่เหนือเส้นฐาน
หมวดส่วนต่างจากเส้นฐาน
ระยอง20.1
นครปฐม15.3
พิษณุโลก10.0
อุดรธานี5.00
สุราษฎร์ธานี4.90
สงขลา-0.10
นครราชสีมา-1.30
ภูเก็ต-6.10
ชลบุรี-9.00
เชียงใหม่-13.0
ขอนแก่น-14.3
กรุงเทพฯ-20.7

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

  • การเรียงลำดับ: เรียงตามค่าจะเห็น "เส้นแบ่ง" ระหว่างกลุ่มที่ดีขึ้นกับแย่ลงทันที ส่วนเรียงตามตัวอักษรจะทำให้ต้องนับเอง

ข้อควรระวัง

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

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

  • ค่าทั้งหมดเป็นบวกใช้แทน: horizontal-bar
  • ข้อมูลเป็นสเกลความเห็นที่มีลำดับใช้แทน: sentiment-diverging ที่จัดกึ่งกลางที่ความเห็นกลาง
  • ต้องการเห็นค่าก่อนและหลังทั้งคู่ใช้แทน: dumbbell-chart

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

เทคนิคถัดไป · กราฟอมยิ้ม