01ภาพรวมของกราฟนี้
Gantt chart วางงานเป็นแถวและวาดแท่งที่กินช่วงเวลาตั้งแต่วันเริ่มถึงวันจบ สิ่งที่อ่านได้คือความยาวของแต่ละงาน การทับซ้อนระหว่างงาน และช่องว่างที่ไม่มีงานทำ ซึ่งเป็นข้อมูลที่ตารางวันที่บอกไม่ได้
เปรียบเทียบให้เห็นภาพ
เหมือนตารางจองห้องประชุมที่วางเวลาไว้แกนนอน เราเห็นทันทีว่าห้องไหนว่างตอนไหนและมีการจองซ้อนกันหรือไม่
ใช้ที่ไหนบ้าง — แผนโครงการ ตารางการผลิต ตารางออกอากาศ หรือช่วงเวลาของเหตุการณ์หลายอย่างที่ทับซ้อนกัน
สร้างอย่างไร
- ขั้นที่ 1ระบุวันเริ่มและวันจบของทุกงาน
- ขั้นที่ 2เรียงงานตามวันเริ่ม
- ขั้นที่ 3วาดแท่งตามช่วงเวลา
- ขั้นที่ 4ทำเครื่องหมายจุดสำคัญและงานที่รอกัน
ตัวอย่างคลาสสิก · Henry Gantt กับการวางแผนการผลิตในสงครามโลกครั้งที่หนึ่ง
Gantt พัฒนาแผนภูมินี้ขึ้นในทศวรรษ 1910 เพื่อวางแผนการผลิตอาวุธของกองทัพสหรัฐ ความคิดหลักคือแทนที่จะดูว่างานแต่ละชิ้นเสร็จหรือยัง ให้ดูว่างานทั้งหมดวางตัวอย่างไรบนแกนเวลาเดียวกัน ซึ่งเผยให้เห็นคอขวดที่ตารางรายงานปกติซ่อนไว้
02อธิบายภาษาคนเข้าใจง่าย ๆ
ตารางที่มีคอลัมน์วันเริ่มและวันจบบอกข้อมูลครบก็จริง แต่การอ่านว่างานไหนซ้อนกับงานไหนต้องเทียบวันทีละคู่ในหัว ซึ่งเกิน 5 งานก็ทำไม่ไหวแล้ว
แผนภูมิแกนต์เปลี่ยนวันที่ให้เป็นตำแหน่งบนแกนนอน ทันทีที่ทำแบบนั้น การทับซ้อนก็กลายเป็นสิ่งที่เห็นด้วยตาโดยไม่ต้องคำนวณ
ข้อมูลที่ได้ฟรีคือความยาวของแท่งซึ่งคือระยะเวลาของงาน และช่องว่างระหว่างแท่งซึ่งคือช่วงที่ไม่มีงานนั้นทำอยู่
สิ่งที่แผนภูมิแกนต์พื้นฐานไม่ได้บอกคือ "ทำไม" งานหนึ่งถึงต้องรออีกงาน ถ้าความสัมพันธ์นั้นสำคัญ ต้องเพิ่มลูกศรเชื่อมระหว่างงาน ซึ่งทำให้ภาพรกขึ้นมาก
ข้อควรระวังที่พบบ่อยในการใช้งานจริงคือ แผนภูมิแกนต์แสดง "แผน" ไม่ใช่ "ความจริง" ถ้าไม่อัปเดตตามความคืบหน้าจริง มันจะกลายเป็นภาพที่ดูเป็นระเบียบแต่ไม่ตรงกับสิ่งที่เกิดขึ้น
03ข้อมูลที่ต้องใช้
คอลัมน์ที่ต้องเตรียม
| คอลัมน์ | ทำหน้าที่ | ชนิด | เข้ารหัสด้วย | จำนวนค่าที่เหมาะ | หมายเหตุ |
|---|---|---|---|---|---|
task | ชื่องาน | หมวดหมู่ | y | 3–30 งาน | หนึ่งแถวหนึ่งงาน |
start | วันเริ่ม | เวลา | x | วันที่ | ต้องอยู่ก่อนวันจบเสมอ |
end | วันจบ | เวลา | x | วันที่ | คู่กับวันเริ่ม |
ต้องเตรียมข้อมูลอย่างไรก่อนวาด
- ตรวจว่าวันเริ่มอยู่ก่อนวันจบทุกแถว
- เรียงงานตามวันเริ่มหรือตามเฟสของโครงการ
- ระบุว่าวันที่เป็นแผนหรือของจริง
ค่าที่หายไป — งานที่ยังไม่กำหนดวันจบให้วาดแท่งที่ปลายเปิดพร้อมสัญลักษณ์ ห้ามเดาวันจบเอง
สเกลของแกน — แกนเวลาเป็นเชิงเส้นตามวันจริงเสมอ ห้ามย่อช่วงที่ไม่มีงานเพราะจะทำให้ระยะเวลาผิด
กราฟจะเริ่มพังเมื่อไร
เกิน 40 งาน ต้องเลื่อนหน้าจนเทียบงานบนกับล่างไม่ได้ — จัดกลุ่มเป็นเฟสแล้วยุบได้
หน้าตาไฟล์ที่ต้องเตรียม
task,start,end
…04อ่านแล้วเห็นอะไร
สิ่งที่เห็นได้จากภาพ
- งานไหนยาวที่สุด
- ช่วงที่มีหลายงานทับซ้อนกันซึ่งคือช่วงที่ทีมงานหนัก
- ช่องว่างที่ไม่มีงานทำ
สิ่งที่กราฟนี้ตอบไม่ได้
- ไม่บอกว่างานไหนต้องรองานไหนถ้าไม่มีลูกศรเชื่อม
- ไม่บอกความคืบหน้าจริงถ้าไม่มีแถบซ้อนแสดงเปอร์เซ็นต์
อ่านตามลำดับนี้
- ดูความยาวรวมของโครงการจากซ้ายสุดถึงขวาสุด
- มองแนวตั้งหาช่วงที่มีหลายแท่งซ้อนกัน
- หางานที่ยาวผิดปกติ
คำถามที่ตอบได้
- โครงการจะเสร็จเมื่อไร
- ช่วงไหนที่งานหนักที่สุด
- ถ้างานนี้ช้าจะกระทบใครบ้าง
สัญญาณว่ามีอะไรผิด
- แกนเวลาถูกย่อในช่วงที่ไม่มีงาน ทำให้ระยะเวลาผิด
- ไม่ระบุว่าเป็นแผนหรือของจริง
05เหมาะกับการนำเสนอแบบไหน
ทำอย่างไรให้คนอ่านได้ข้อสรุปโดยไม่ต้องบรรยาย
- ลากเส้นแนวตั้งของวันนี้เพื่อให้เห็นว่าอยู่ตรงไหนของแผน
- ทำเครื่องหมายจุดสำคัญด้วยสัญลักษณ์เพชร
- ใช้สีบอกเฟสหรือทีมที่รับผิดชอบ
รูปแบบชื่อกราฟที่ควรใช้
โครงการใช้เวลา <ระยะเวลา> โดยช่วง <เวลา> มีงานทับซ้อน <จำนวน> งาน
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), "แถว")07ลองเล่นเพื่อเข้าใจ
ดูข้อมูลเป็นตาราง (7 แถว)
| งาน | เริ่ม | จบ | จำนวนวัน |
|---|---|---|---|
| สำรวจความต้องการ | 2025-03-03 | 2025-03-17 | 14 |
| ออกแบบ | 2025-03-12 | 2025-04-04 | 23 |
| พัฒนา | 2025-03-26 | 2025-04-13 | 18 |
| ทดสอบ | 2025-04-06 | 2025-04-21 | 15 |
| อบรมผู้ใช้ | 2025-04-15 | 2025-05-08 | 23 |
| เปิดใช้งาน | 2025-04-29 | 2025-05-22 | 23 |
| ติดตามผล | 2025-05-13 | 2025-06-10 | 28 |
ลองแล้วจะเห็นอะไร
- สังเกตอะไร: ลากสายตาในแนวตั้งที่ตำแหน่งเวลาหนึ่ง แล้วนับว่ามีกี่แท่งพาดผ่าน นั่นคือจำนวนงานที่ต้องทำพร้อมกันในวันนั้น ซึ่งตารางวันที่บอกไม่ได้
ข้อควรระวัง
- ย่อแกนเวลาในช่วงที่ไม่มีงาน ทำให้ระยะเวลาที่เห็นผิดจากความจริง
- ไม่ระบุว่าเป็นแผนหรือความคืบหน้าจริง
- ใส่งานมากเกินไปจนต้องเลื่อนหน้าและเทียบกันไม่ได้
- ใส่ลูกศรเชื่อมทุกความสัมพันธ์จนภาพรกจนอ่านไม่ออก
เมื่อไหร่ไม่ควรใช้กราฟนี้
- สนใจลำดับการพึ่งพามากกว่าช่วงเวลา→ใช้แทน: flow-diagram หรือ node-link-tree
- งานทุกงานยาวเท่ากันและไม่ทับซ้อน→ใช้แทน: ตารางวันที่ธรรมดา
- ต้องการดูภาระงานรวมตามเวลา→ใช้แทน: stacked-area ของจำนวนงานที่ทำพร้อมกัน