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

แผนภูมิแกนต์Gantt Chart

เห็นว่างานไหนซ้อนทับกันและอะไรรอใคร

3
ผสานหลายแนวคิดควรรู้ก่อน · อ่านแกนเวลาเป็น
ลองเล่น

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

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

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

เหมือนตารางจองห้องประชุมที่วางเวลาไว้แกนนอน เราเห็นทันทีว่าห้องไหนว่างตอนไหนและมีการจองซ้อนกันหรือไม่

ใช้ที่ไหนบ้าง — แผนโครงการ ตารางการผลิต ตารางออกอากาศ หรือช่วงเวลาของเหตุการณ์หลายอย่างที่ทับซ้อนกัน

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

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

ตัวอย่างคลาสสิก · Henry Gantt กับการวางแผนการผลิตในสงครามโลกครั้งที่หนึ่ง

Gantt พัฒนาแผนภูมินี้ขึ้นในทศวรรษ 1910 เพื่อวางแผนการผลิตอาวุธของกองทัพสหรัฐ ความคิดหลักคือแทนที่จะดูว่างานแต่ละชิ้นเสร็จหรือยัง ให้ดูว่างานทั้งหมดวางตัวอย่างไรบนแกนเวลาเดียวกัน ซึ่งเผยให้เห็นคอขวดที่ตารางรายงานปกติซ่อนไว้

Wikipedia · Gantt chart

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

ตารางที่มีคอลัมน์วันเริ่มและวันจบบอกข้อมูลครบก็จริง แต่การอ่านว่างานไหนซ้อนกับงานไหนต้องเทียบวันทีละคู่ในหัว ซึ่งเกิน 5 งานก็ทำไม่ไหวแล้ว

แผนภูมิแกนต์เปลี่ยนวันที่ให้เป็นตำแหน่งบนแกนนอน ทันทีที่ทำแบบนั้น การทับซ้อนก็กลายเป็นสิ่งที่เห็นด้วยตาโดยไม่ต้องคำนวณ

ข้อมูลที่ได้ฟรีคือความยาวของแท่งซึ่งคือระยะเวลาของงาน และช่องว่างระหว่างแท่งซึ่งคือช่วงที่ไม่มีงานนั้นทำอยู่

สิ่งที่แผนภูมิแกนต์พื้นฐานไม่ได้บอกคือ "ทำไม" งานหนึ่งถึงต้องรออีกงาน ถ้าความสัมพันธ์นั้นสำคัญ ต้องเพิ่มลูกศรเชื่อมระหว่างงาน ซึ่งทำให้ภาพรกขึ้นมาก

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

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

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

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

คอลัมน์ทำหน้าที่ชนิดเข้ารหัสด้วยจำนวนค่าที่เหมาะหมายเหตุ
taskชื่องานหมวดหมู่y3–30 งานหนึ่งแถวหนึ่งงาน
startวันเริ่มเวลาxวันที่ต้องอยู่ก่อนวันจบเสมอ
endวันจบเวลาxวันที่คู่กับวันเริ่ม

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

  1. ตรวจว่าวันเริ่มอยู่ก่อนวันจบทุกแถว
  2. เรียงงานตามวันเริ่มหรือตามเฟสของโครงการ
  3. ระบุว่าวันที่เป็นแผนหรือของจริง

ค่าที่หายไป — งานที่ยังไม่กำหนดวันจบให้วาดแท่งที่ปลายเปิดพร้อมสัญลักษณ์ ห้ามเดาวันจบเอง

สเกลของแกน — แกนเวลาเป็นเชิงเส้นตามวันจริงเสมอ ห้ามย่อช่วงที่ไม่มีงานเพราะจะทำให้ระยะเวลาผิด

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

เกิน 40 งาน ต้องเลื่อนหน้าจนเทียบงานบนกับล่างไม่ได้ — จัดกลุ่มเป็นเฟสแล้วยุบได้

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

task,start,end

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

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

  • งานไหนยาวที่สุด
  • ช่วงที่มีหลายงานทับซ้อนกันซึ่งคือช่วงที่ทีมงานหนัก
  • ช่องว่างที่ไม่มีงานทำ

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

  • ไม่บอกว่างานไหนต้องรองานไหนถ้าไม่มีลูกศรเชื่อม
  • ไม่บอกความคืบหน้าจริงถ้าไม่มีแถบซ้อนแสดงเปอร์เซ็นต์

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

  1. ดูความยาวรวมของโครงการจากซ้ายสุดถึงขวาสุด
  2. มองแนวตั้งหาช่วงที่มีหลายแท่งซ้อนกัน
  3. หางานที่ยาวผิดปกติ

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

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

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

  • แกนเวลาถูกย่อในช่วงที่ไม่มีงาน ทำให้ระยะเวลาผิด
  • ไม่ระบุว่าเป็นแผนหรือของจริง

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

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

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

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

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

โครงการใช้เวลา <ระยะเวลา> โดยช่วง <เวลา> มีงานทับซ้อน <จำนวน> งาน

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

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

# ติดตั้ง: pip install "matplotlib==3.10.*" "pandas==2.*"
# ดาวน์โหลด gantt-chart-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("gantt-chart-sample.csv")

NOTE = "overlap"   # ← ค่าจาก Playground

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

df["start"] = pd.to_datetime(df["start"]); df["end"] = pd.to_datetime(df["end"])
d = df.sort_values("start", ascending=False)      # ascending=False เพราะ barh วาดจากล่างขึ้นบน
ax.barh(d["task"], (d["end"] - d["start"]).dt.days, left=d["start"], height=0.58, color=C1)
ax.axvline(d["start"].min(), color=INK, linestyle="--", linewidth=1)   # เส้นวันเริ่มโครงการ
ax.set_xlabel("วันที่")
fig.autofmt_xdate()

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

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

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

ข้อมูลตัวอย่าง · 7 แถว · seed 71● คำนวณใหม่ในเบราว์เซอร์ทันทีที่ปรับค่า
มองแนวตั้งเพื่อหาช่วงที่งานหนัก
15 มี.ค.7 เม.ย.30 เม.ย.23 พ.ค.สำรวจความต้องการสำรวจความต้องการ · 3/3/2568 → 17/3/2568ออกแบบออกแบบ · 12/3/2568 → 4/4/2568พัฒนาพัฒนา · 26/3/2568 → 13/4/2568ทดสอบทดสอบ · 6/4/2568 → 21/4/2568อบรมผู้ใช้อบรมผู้ใช้ · 15/4/2568 → 8/5/2568เปิดใช้งานเปิดใช้งาน · 29/4/2568 → 22/5/2568ติดตามผลติดตามผล · 13/5/2568 → 10/6/2568
ระยะเวลารวม99 วัน
งานที่ทับซ้อนกับงานอื่น7 จาก 7
งานที่ยาวที่สุดติดตามผล
ดูข้อมูลเป็นตาราง (7 แถว)
gantt chart 7 งาน ระยะเวลารวม 99 วัน
งานเริ่มจบจำนวนวัน
สำรวจความต้องการ2025-03-032025-03-1714
ออกแบบ2025-03-122025-04-0423
พัฒนา2025-03-262025-04-1318
ทดสอบ2025-04-062025-04-2115
อบรมผู้ใช้2025-04-152025-05-0823
เปิดใช้งาน2025-04-292025-05-2223
ติดตามผล2025-05-132025-06-1028

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

  • สังเกตอะไร: ลากสายตาในแนวตั้งที่ตำแหน่งเวลาหนึ่ง แล้วนับว่ามีกี่แท่งพาดผ่าน นั่นคือจำนวนงานที่ต้องทำพร้อมกันในวันนั้น ซึ่งตารางวันที่บอกไม่ได้

ข้อควรระวัง

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

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

  • สนใจลำดับการพึ่งพามากกว่าช่วงเวลาใช้แทน: flow-diagram หรือ node-link-tree
  • งานทุกงานยาวเท่ากันและไม่ทับซ้อนใช้แทน: ตารางวันที่ธรรมดา
  • ต้องการดูภาระงานรวมตามเวลาใช้แทน: stacked-area ของจำนวนงานที่ทำพร้อมกัน

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

เทคนิคถัดไป · ฮิสโทแกรม