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

แผนที่ชุดเปรียบเทียบSmall Multiple Maps

เห็นว่ารูปแบบเชิงพื้นที่เปลี่ยนไปอย่างไร

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

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

Small multiple maps วางแผนที่หลายภาพเรียงกันโดยใช้สเกลสีเดียวกันทุกภาพ ทำให้เห็นการเปลี่ยนแปลงเชิงพื้นที่ตามเวลาได้โดยไม่ต้องอาศัยแอนิเมชันหรือความจำ กฎเหล็กคือทุกภาพต้องใช้สเกลเดียวกัน ไม่อย่างนั้นการเทียบกันก็ไร้ความหมาย

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

เหมือนภาพถ่ายดาวเทียมชุดเดียวกันถ่ายห่างกันปีละภาพ ซึ่งวางเรียงแล้วเห็นป่าหายไปทีละน้อย

ใช้ที่ไหนบ้าง — การแพร่ระบาดของโรคตามเวลา การขยายตัวของเมือง การเปลี่ยนแปลงผลการเลือกตั้งข้ามรอบ หรือการเทียบตัวชี้วัดหลายตัวในพื้นที่เดียวกัน

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

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

ตัวอย่างคลาสสิก · แผนที่ชุดแสดงการระบาดของโรคหัดก่อนและหลังมีวัคซีน

The Wall Street Journal เผยแพร่ภาพชุดแผนที่อัตราการเกิดโรคติดต่อรายรัฐเรียงตามปี โดยใช้สเกลสีเดียวกันทั้งหมด เส้นแบ่งที่ปีที่เริ่มใช้วัคซีนปรากฏชัดเจนจนไม่ต้องอธิบาย และกลายเป็นหนึ่งในภาพข้อมูลที่ถูกแชร์มากที่สุดในทศวรรษนั้น

Wikipedia · Small multiple

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

เมื่ออยากรู้ว่ารูปแบบเชิงพื้นที่เปลี่ยนไปอย่างไร ทางเลือกคือทำแอนิเมชัน หรือวางภาพเรียงกัน

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

Small multiple maps แก้ด้วยการวางทุกช่วงเวลาไว้ให้เห็นพร้อมกัน ผู้อ่านจึงเทียบด้วยการกวาดสายตา ซึ่งแม่นกว่าการจำหลายเท่า และยังย้อนกลับไปดูซ้ำได้ตามใจ

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

ข้อจำกัดคือแต่ละภาพเล็กลงตามจำนวนภาพ จึงเหมาะกับรูปแบบใหญ่ ๆ ที่เห็นได้แม้ภาพเล็ก ไม่เหมาะกับรายละเอียดปลีกย่อย

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

รูปทรงของข้อมูลGeoJSON + ตารางค่าที่ join ด้วย key
จำนวนมิติที่เข้ารหัสได้3 มิติ
จำนวนแถวที่เหมาะ4–9 ภาพย่อยขั้นต่ำ 12 แถว
เส้นฐานศูนย์ไม่เกี่ยวข้องค่าเข้ารหัสด้วยสี ไม่มีแกนค่า

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

คอลัมน์ทำหน้าที่ชนิดเข้ารหัสด้วยจำนวนค่าที่เหมาะหมายเหตุ
provinceเขตพื้นที่เชิงพื้นที่shape10–80 เขตชุดเดียวกันทุกภาพ
regionช่วงเวลาหรือกลุ่มมีลำดับcolumn3–12 ภาพแต่ละค่าเป็นหนึ่งภาพย่อย
rateค่าที่วัดตัวเลขต่อเนื่องcolorต่อเนื่อง★ สเกลสีต้องมาจากข้อมูลทุกภาพรวมกัน

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

  1. ★ คำนวณช่วงค่าจากข้อมูลทุกภาพรวมกันก่อนกำหนดสเกลสี
  2. ตรวจว่าทุกภาพมีเขตครบชุดเดียวกัน
  3. เรียงภาพตามลำดับเวลา

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

สเกลของแกน — ★ สเกลสีเดียวกันทุกภาพโดยไม่มีข้อยกเว้น และมุมมองกับขนาดต้องเท่ากันหมด

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

เกิน 12 ภาพ แต่ละภาพเล็กจนไม่เห็นรูปแบบ

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

province,region,rate
กรุงเทพฯ,เหนือ,26.6
เชียงใหม่,อีสาน,34.7

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

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

  • ทิศทางการเปลี่ยนแปลงเชิงพื้นที่ตามเวลา
  • บริเวณที่เปลี่ยนเร็วที่สุด
  • บริเวณที่ไม่เปลี่ยนเลย
  • จุดเริ่มต้นของการแพร่กระจาย

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

  • ★ รายละเอียดปลีกย่อย เพราะแต่ละภาพเล็กลงตามจำนวนภาพ
  • ค่าที่แม่นยำของแต่ละเขตในแต่ละภาพ

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

  1. ดูภาพแรกและภาพสุดท้ายก่อนเพื่อรู้ทิศทางรวม
  2. กวาดสายตาตามลำดับเพื่อดูว่าเปลี่ยนตอนไหน
  3. เลือกเขตหนึ่งแล้วตามเขตนั้นข้ามทุกภาพ

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

  • รูปแบบเชิงพื้นที่เปลี่ยนไปอย่างไร
  • เริ่มจากที่ไหนแล้วลามไปทางไหน
  • ที่ไหนเปลี่ยนเร็วที่สุด

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

  • แต่ละภาพใช้สเกลสีของตัวเอง
  • ภาพขนาดหรือมุมมองไม่เท่ากัน
  • ข้ามช่วงเวลาที่ไม่มีข้อมูลโดยไม่บอก

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

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

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

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

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

<ตัวชี้วัด> ระหว่าง <ช่วงแรก> ถึง <ช่วงสุดท้าย> โดยใช้สเกลสีเดียวกันทุกภาพ

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

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

# ติดตั้ง: pip install "matplotlib==3.10.*" "pandas==2.*"
# ดาวน์โหลด small-multiple-maps-sample.csv จากหน้านี้ แล้ววางไว้ข้างสคริปต์
import matplotlib
matplotlib.use("Agg")   # รันแบบไม่มีหน้าจอ ถ้ารันในเครื่องตัวเองลบบรรทัดนี้ได้
import matplotlib.pyplot as plt
import pandas as pd
import geopandas as gpd
import matplotlib.pyplot as plt

C1, C2, C3 = "#2a78d6", "#eb6834", "#1baf7a"   # palette ของคลัง เปลี่ยนเป็นสีองค์กรได้
INK, SURFACE = "#0b0b0b", "#fcfcfb"

df = pd.read_csv("small-multiple-maps-sample.csv")
df["rate"] = pd.to_numeric(df["rate"], errors="coerce")
NOTE = "scale"   # ← ค่าจาก Playground

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

periods = sorted(df["period"].unique())
vmin, vmax = df["rate"].min(), df["rate"].max()          # ★ สเกลร่วมจากข้อมูลทุกช่วง
fig, axes = plt.subplots(2, 3, figsize=(11, 7), constrained_layout=True)
base = gpd.read_file("provinces.geojson")
for ax_, p in zip(axes.ravel(), periods):
    g = base.merge(df[df["period"] == p], on="province")
    g.plot(column="rate", cmap="Blues", vmin=vmin, vmax=vmax,   # vmin/vmax เหมือนกันหมด
           ax=ax_, edgecolor="#fcfcfb", linewidth=0.4)
    ax_.set_title(str(p), fontsize=10, loc="left"); ax_.set_axis_off()
fig.colorbar(plt.cm.ScalarMappable(cmap="Blues",
             norm=plt.Normalize(vmin, vmax)), ax=axes, shrink=0.6, label="ต่อประชากรหมื่นคน")

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

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

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

ข้อมูลตัวอย่าง · 16 แถว · seed 331● คำนวณใหม่ในเบราว์เซอร์ทันทีที่ปรับค่า
ทุกภาพใช้สเกลเดียวกัน
ไตรมาส 1ไตรมาส 1 · กรุงเทพฯ · 21.8ไตรมาส 1 · เชียงใหม่ · 28.5ไตรมาส 1 · ขอนแก่น · 26.8ไตรมาส 1 · ชลบุรี · 28.2ไตรมาส 1 · ภูเก็ต · 22.0ไตรมาส 1 · นครราชสีมา · 15.0ไตรมาส 1 · สงขลา · 8.53ไตรมาส 1 · อุดรธานี · 18.9ไตรมาส 1 · สุราษฎร์ธานี · 16.5ไตรมาส 1 · พิษณุโลก · 14.7ไตรมาส 1 · ระยอง · 14.3ไตรมาส 1 · นครปฐม · 8.61ไตรมาส 2ไตรมาส 2 · กรุงเทพฯ · 25.0ไตรมาส 2 · เชียงใหม่ · 32.6ไตรมาส 2 · ขอนแก่น · 30.7ไตรมาส 2 · ชลบุรี · 32.3ไตรมาส 2 · ภูเก็ต · 25.2ไตรมาส 2 · นครราชสีมา · 17.2ไตรมาส 2 · สงขลา · 9.78ไตรมาส 2 · อุดรธานี · 21.7ไตรมาส 2 · สุราษฎร์ธานี · 18.9ไตรมาส 2 · พิษณุโลก · 16.8ไตรมาส 2 · ระยอง · 16.4ไตรมาส 2 · นครปฐม · 9.87ไตรมาส 3ไตรมาส 3 · กรุงเทพฯ · 28.2ไตรมาส 3 · เชียงใหม่ · 36.8ไตรมาส 3 · ขอนแก่น · 34.7ไตรมาส 3 · ชลบุรี · 36.5ไตรมาส 3 · ภูเก็ต · 28.4ไตรมาส 3 · นครราชสีมา · 19.4ไตรมาส 3 · สงขลา · 11.0ไตรมาส 3 · อุดรธานี · 24.5ไตรมาส 3 · สุราษฎร์ธานี · 21.3ไตรมาส 3 · พิษณุโลก · 19.0ไตรมาส 3 · ระยอง · 18.4ไตรมาส 3 · นครปฐม · 11.1ไตรมาส 4ไตรมาส 4 · กรุงเทพฯ · 31.4ไตรมาส 4 · เชียงใหม่ · 40.9ไตรมาส 4 · ขอนแก่น · 38.6ไตรมาส 4 · ชลบุรี · 40.6ไตรมาส 4 · ภูเก็ต · 31.6ไตรมาส 4 · นครราชสีมา · 21.6ไตรมาส 4 · สงขลา · 12.3ไตรมาส 4 · อุดรธานี · 27.3ไตรมาส 4 · สุราษฎร์ธานี · 23.7ไตรมาส 4 · พิษณุโลก · 21.1ไตรมาส 4 · ระยอง · 20.5ไตรมาส 4 · นครปฐม · 12.410.434.7

ถ้าแต่ละแผงใช้สเกลสีของตัวเอง การเทียบข้ามแผงจะไม่มีความหมาย — ต้องใช้สเกลร่วมเสมอ

จำนวนแผง4
สเกลสีใช้ร่วมกันทุกแผง
พื้นที่ต่อแผง12
ดูข้อมูลเป็นตาราง (12 แถว)
small multiple maps 4 ช่วงเวลา
จังหวัดไตรมาส 1ไตรมาส 2ไตรมาส 3ไตรมาส 4
กรุงเทพฯ21.825.028.231.4
เชียงใหม่28.532.636.840.9
ขอนแก่น26.830.734.738.6
ชลบุรี28.232.336.540.6
ภูเก็ต22.025.228.431.6
นครราชสีมา15.017.219.421.6
สงขลา8.539.7811.012.3
อุดรธานี18.921.724.527.3
สุราษฎร์ธานี16.518.921.323.7
พิษณุโลก14.716.819.021.1
ระยอง14.316.418.420.5
นครปฐม8.619.8711.112.4

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

  • สังเกตอะไร: ลองจินตนาการว่าแต่ละภาพใช้สเกลของตัวเอง สีเดียวกันจะแทนค่าคนละค่า และการเทียบทั้งหมดก็พังทันที

ข้อควรระวัง

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

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

  • มีช่วงเวลาเดียวใช้แทน: choropleth-map
  • สนใจแนวโน้มของตัวเลขมากกว่าตำแหน่งใช้แทน: line-chart หรือ slope-graph
  • มีมากกว่า 12 ช่วงเวลาใช้แทน: heatmap-matrix ที่แกนหนึ่งเป็นเวลา

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

เทคนิคถัดไป · แผนที่ช่องเท่ากัน