01ภาพรวมของกราฟนี้
Multi-line chart เทียบแนวโน้มของหลายอนุกรมพร้อมกัน สิ่งที่มีค่าที่สุดคือจุดตัดและช่องว่างระหว่างเส้น ซึ่งบอกเรื่องที่กราฟเส้นเดียวเล่าไม่ได้ ข้อจำกัดคือจำนวนเส้น เพราะเกิน 5-6 เส้นจะกลายเป็นพันกันจนอ่านไม่ได้
เปรียบเทียบให้เห็นภาพ
เหมือนดูการแข่งวิ่งจากด้านข้าง เราเห็นว่าใครนำอยู่ ใครกำลังไล่ และแซงกันตอนไหน ซึ่งการดูเวลาเข้าเส้นชัยอย่างเดียวบอกไม่ได้
ใช้ที่ไหนบ้าง — เทียบยอดขายหลายช่องทางตามเวลา เทียบจำนวนผู้ใช้หลายแพลตฟอร์ม หรือเทียบตัวชี้วัดของเรากับคู่แข่ง
สร้างอย่างไร
- ขั้นที่ 1ตรวจว่าทุกอนุกรมใช้หน่วยเดียวกัน
- ขั้นที่ 2จำกัดจำนวนเส้นไม่เกิน 5-6 เส้น
- ขั้นที่ 3ติดป้ายชื่อไว้ปลายเส้นแทนการพึ่ง legend
- ขั้นที่ 4เน้นเส้นที่เป็นประเด็นและทำเส้นอื่นเป็นสีเทา
ตัวอย่างคลาสสิก · กราฟเปรียบเทียบการระบาดของโรคระหว่างประเทศ
ช่วงการระบาดใหญ่ กราฟหลายเส้นที่วางจำนวนผู้ติดเชื้อของแต่ละประเทศบนแกนเดียวกันกลายเป็นภาพที่คนทั้งโลกดูทุกวัน และเป็นบทเรียนสาธารณะครั้งใหญ่ว่าการเลือกสเกลแบบ log หรือ linear เปลี่ยนข้อสรุปได้มากแค่ไหน
02อธิบายภาษาคนเข้าใจง่าย ๆ
เมื่อต้องเทียบแนวโน้มของหลายกลุ่ม การวางทุกเส้นบนแกนเดียวกันทำให้เห็นสิ่งที่กราฟแยกกันไม่มีวันบอกได้ นั่นคือจุดที่เส้นตัดกันและช่องว่างระหว่างเส้นที่กว้างขึ้นหรือแคบลง
ข้อบังคับข้อแรกคือทุกเส้นต้องใช้หน่วยเดียวกัน ถ้าเส้นหนึ่งเป็นบาทและอีกเส้นเป็นเปอร์เซ็นต์ ห้ามใส่แกนที่สองเด็ดขาด เพราะแกนที่สองทำให้ผู้ทำกราฟเลือกได้ว่าจะให้เส้นไหนดูสูงกว่า ซึ่งเป็นการบิดข้อมูลที่พบบ่อยที่สุด
ทางแก้ที่ถูกต้องเมื่อหน่วยต่างกันมีสองทาง คือแยกเป็นกราฟย่อยหลายอัน หรือแปลงทุกเส้นเป็นดัชนีที่เริ่มจากฐานเดียวกัน เช่น ให้ทุกเส้นเริ่มที่ 100 แล้วดูการเติบโตเป็นเปอร์เซ็นต์
จำนวนเส้นเป็นข้อจำกัดจริง เกิน 5-6 เส้นแล้วภาพจะกลายเป็นก้อนเส้นพันกัน ทางออกคือเน้นเส้นเดียวที่เป็นประเด็นด้วยสีเข้ม แล้วทำเส้นที่เหลือเป็นสีเทาจาง ๆ เป็นฉากหลัง
ป้ายชื่อควรติดไว้ที่ปลายเส้นทางขวา แทนที่จะให้ผู้อ่านสลับสายตาไปมาระหว่างกราฟกับ legend ซึ่งเป็นภาระทางความคิดที่ตัดออกได้ฟรี
03ข้อมูลที่ต้องใช้
คอลัมน์ที่ต้องเตรียม
| คอลัมน์ | ทำหน้าที่ | ชนิด | เข้ารหัสด้วย | จำนวนค่าที่เหมาะ | หมายเหตุ |
|---|---|---|---|---|---|
date | เวลา | เวลา | x | 10–200 จุด | ทุกอนุกรมควรมีจุดเวลาเดียวกัน |
series | ชื่ออนุกรม | หมวดหมู่ | color | 2–6 เส้น | เกิน 6 เส้นให้ fold เป็น "อื่น ๆ" หรือแยกเป็น small multiples |
value | ค่าที่วัดได้ | ตัวเลขต่อเนื่อง | y | ต่อเนื่อง | ★ ทุกอนุกรมต้องเป็นหน่วยเดียวกัน ห้ามใช้แกนที่สอง |
ต้องเตรียมข้อมูลอย่างไรก่อนวาด
- ตรวจว่าทุกอนุกรมใช้หน่วยเดียวกัน
- จัดให้ทุกอนุกรมมีจุดเวลาตรงกัน
- ถ้าหน่วยต่างกันให้แปลงเป็นดัชนีฐานเดียวกันก่อน
- ตัดสินใจว่าเส้นไหนคือพระเอกของเรื่อง
ค่าที่หายไป — หักเส้นตรงช่วงที่ไม่มีข้อมูลของอนุกรมนั้น และอย่าปล่อยให้เส้นอื่นทำให้ดูเหมือนข้อมูลครบ
สเกลของแกน — linear เมื่อสนใจค่าสัมบูรณ์ ใช้ log หรือดัชนีฐาน 100 เมื่อสนใจอัตราการเติบโตเทียบกัน
กราฟจะเริ่มพังเมื่อไร
เกิน 6 เส้น ภาพกลายเป็นก้อนเส้นพันกัน — ใช้ small-multiples หรือ highlight ทีละเส้น
หน้าตาไฟล์ที่ต้องเตรียม
date,series,value
…04อ่านแล้วเห็นอะไร
สิ่งที่เห็นได้จากภาพ
- เส้นไหนนำและตามในแต่ละช่วง
- จุดที่เส้นตัดกัน ซึ่งมักเป็นเหตุการณ์สำคัญ
- ช่องว่างระหว่างเส้นกว้างขึ้นหรือแคบลง
- เส้นที่เคลื่อนไปคนละทางกับเส้นอื่น
สิ่งที่กราฟนี้ตอบไม่ได้
- ไม่บอกยอดรวมของทุกอนุกรม ต้องใช้ stacked-area
- ไม่บอกว่าเส้นที่เคลื่อนไปด้วยกันเป็นเหตุและผลกัน
อ่านตามลำดับนี้
- หาเส้นที่เป็นประเด็นก่อนจากสีที่เด่น
- ดูว่ามีจุดตัดกันตรงไหนบ้าง
- ดูว่าช่องว่างระหว่างเส้นเปลี่ยนไปอย่างไร
คำถามที่ตอบได้
- ใครนำอยู่ตอนนี้
- แซงกันเมื่อไร
- ช่องว่างระหว่างสองกลุ่มกำลังปิดหรือไม่
สัญญาณว่ามีอะไรผิด
- ★ มีแกน y สองแกน ซึ่งทำให้เลือกได้ว่าจะให้เส้นไหนดูสูงกว่า
- เส้นเกิน 6 เส้นสีใกล้เคียงกัน
- ไม่มีป้ายชื่อที่ปลายเส้น
05เหมาะกับการนำเสนอแบบไหน
ทำอย่างไรให้คนอ่านได้ข้อสรุปโดยไม่ต้องบรรยาย
- ติดชื่ออนุกรมไว้ปลายเส้นขวาสุดแทน legend
- ทำเครื่องหมายจุดตัดที่สำคัญ
- ทำเส้นที่ไม่ใช่ประเด็นเป็นสีเทา
รูปแบบชื่อกราฟที่ควรใช้
<อนุกรม> แซง <อนุกรม> เมื่อ <เวลา> และทิ้งห่างเป็น <ช่องว่าง>
06เอาไปใช้ต่อ
โค้ดทุกชิ้นอ่านไฟล์ multi-line-chart-sample.csv ชุดเดียวกับที่ Playground ใช้ และตัวเลขในโค้ดเปลี่ยนตามค่าที่คุณปรับด้านล่าง
# ติดตั้ง: pip install "matplotlib==3.10.*" "pandas==2.*"
# ดาวน์โหลด multi-line-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("multi-line-chart-sample.csv")
df["value"] = pd.to_numeric(df["value"], errors="coerce")
NOTE = "cross" # ← ค่าจาก Playground
fig, ax = plt.subplots(figsize=(7.6, 4.2), facecolor=SURFACE)
ax.set_facecolor(SURFACE)
df["date"] = pd.to_datetime(df["date"])
for i, (name, g) in enumerate(df.groupby("series")):
g = g.sort_values("date")
ax.plot(g["date"], g["value"], color=[C1, C2, C3][i % 3], linewidth=2, label=name)
ax.annotate(name, (g["date"].iloc[-1], g["value"].iloc[-1]), xytext=(6, 0),
textcoords="offset points", fontsize=9, color=[C1, C2, C3][i % 3]) # ป้ายที่ปลายเส้น
ax.grid(axis="y", alpha=0.25); ax.set_axisbelow(True)
fig.autofmt_xdate()
ax.spines[["top", "right"]].set_visible(False) # ลดเส้นที่ไม่ได้ให้ข้อมูล
fig.tight_layout()
fig.savefig("multi-line-chart.png", dpi=160)
print("เขียน multi-line-chart.png แล้ว ·", len(df), "แถว")07ลองเล่นเพื่อเข้าใจ
ดูข้อมูลเป็นตาราง (26 แถว)
| วันที่ | หน้าร้าน | เว็บไซต์ | แอป |
|---|---|---|---|
| 1/1/2568 | 70.7 | 53.4 | 31.7 |
| 8/1/2568 | 71.3 | 56.1 | 31.8 |
| 15/1/2568 | 68.6 | 58.6 | 31.6 |
| 22/1/2568 | 69.3 | 57.8 | 35.5 |
| 29/1/2568 | 64.7 | 60.9 | 41.4 |
| 5/2/2568 | 64.9 | 65.0 | 40.1 |
| 12/2/2568 | 62.2 | 67.2 | 40.9 |
| 19/2/2568 | 64.4 | 67.5 | 44.3 |
| 26/2/2568 | 63.0 | 65.4 | 48.8 |
| 5/3/2568 | 62.4 | 65.7 | 52.9 |
| 12/3/2568 | 62.3 | 68.5 | 51.8 |
| 19/3/2568 | 63.3 | 72.2 | 51.1 |
| 26/3/2568 | 63.3 | 72.4 | 50.1 |
| 2/4/2568 | 60.2 | 70.8 | 52.2 |
| 9/4/2568 | 56.1 | 73.0 | 56.5 |
| 16/4/2568 | 59.6 | 77.2 | 61.7 |
| 23/4/2568 | 60.1 | 78.0 | 66.8 |
| 30/4/2568 | 58.7 | 80.2 | 67.6 |
| 7/5/2568 | 59.6 | 81.7 | 70.1 |
| 14/5/2568 | 61.8 | 80.9 | 73.8 |
| 21/5/2568 | 60.8 | 78.4 | 73.7 |
| 28/5/2568 | 60.1 | 80.1 | 75.3 |
| 4/6/2568 | 57.9 | 82.6 | 77.7 |
| 11/6/2568 | 56.0 | 83.7 | 78.3 |
| 18/6/2568 | 57.0 | 86.8 | 79.8 |
| 25/6/2568 | 58.3 | 83.5 | 84.4 |
ลองแล้วจะเห็นอะไร
- สังเกตอะไร: หาจุดที่เส้นสองเส้นตัดกัน นั่นคือช่วงเวลาที่อันดับสลับ ซึ่งเป็นข้อมูลที่กราฟแยกกันมองไม่เห็น
ข้อควรระวัง
- ★ ใช้แกน y สองแกนเมื่อหน่วยต่างกัน ซึ่งเป็นความผิดพลาดอันดับหนึ่งของการทำกราฟ
- ใส่เส้นเกิน 6 เส้นจนพันกันและสีแยกไม่ออกสำหรับคนตาบอดสี
- ให้ทุกเส้นเด่นเท่ากันทั้งที่มีเส้นเดียวที่เป็นประเด็น
- ใช้ legend แทนป้ายที่ปลายเส้น ทำให้ผู้อ่านต้องสลับสายตาไปมา
เมื่อไหร่ไม่ควรใช้กราฟนี้
- หน่วยของแต่ละอนุกรมต่างกัน→ใช้แทน: small-multiples หรือแปลงเป็นดัชนีฐาน 100 ก่อน
- มีมากกว่า 6 อนุกรม→ใช้แทน: small-multiples หรือ horizon-chart
- สนใจยอดรวมของทุกอนุกรม→ใช้แทน: stacked-area
- สนใจอันดับมากกว่าค่า→ใช้แทน: bump-chart