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

แผนที่วงกลมตามขนาดGraduated Symbol Map

แสดงจำนวนนับบนแผนที่ได้โดยไม่ให้พื้นที่บิดเบือน

2
ต่อยอดโดยตรงควรรู้ก่อน · เข้าใจว่าพื้นที่แทนปริมาณ
ลองเล่น

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

Graduated symbol map วางวงกลมที่ขนาดแปรตามค่าลงบนแผนที่ จุดแข็งคือแก้ปัญหาที่ choropleth ใช้จำนวนนับไม่ได้ เพราะขนาดวงไม่ขึ้นกับพื้นที่ของเขต แลกกับการที่วงซ้อนกันในบริเวณที่หนาแน่นและอ่านขนาดได้หยาบ

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

เหมือนหมุดที่ปักบนแผนที่โดยหมุดใหญ่แปลว่าเรื่องใหญ่ ซึ่งอ่านง่ายกว่าการดูว่าพื้นที่ไหนถูกระบายเข้ม

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

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

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

ตัวอย่างคลาสสิก · แผนที่การเดินทัพของนโปเลียนโดย Charles Minard

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

Wikipedia · Charles Joseph Minard

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

Choropleth มีข้อจำกัดที่แก้ไม่ได้ คือมันใช้จำนวนนับไม่ได้เลย เพราะพื้นที่ของเขตเข้าไปปนกับค่าที่อยากสื่อ

Graduated symbol map แก้ด้วยการแยกสองสิ่งนี้ออกจากกัน ตำแหน่งบอกว่าอยู่ที่ไหน และขนาดวงบอกว่ามีเท่าไร โดยขนาดของเขตไม่เกี่ยวข้องเลย

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

ราคาที่จ่ายอย่างแรกคือขนาดอ่านได้หยาบกว่าความยาวมาก คนประเมินพื้นที่วงกลมต่ำกว่าความจริงเสมอ จึงต้องมีตารางหรือป้ายค่าประกอบ

อย่างที่สองคือในบริเวณที่จุดหนาแน่น วงจะซ้อนกันจนอ่านไม่ได้ ซึ่งแก้ได้ด้วยการเรียงวาดจากใหญ่ไปเล็กและใส่ความโปร่งใส แต่แก้ได้ไม่หมด

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

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

รูปทรงของข้อมูลGeoJSON + ตารางค่าที่ join ด้วย key
จำนวนมิติที่เข้ารหัสได้3 มิติ
จำนวนแถวที่เหมาะ10–60 จุดขั้นต่ำ 5 แถว
เส้นฐานศูนย์ไม่เกี่ยวข้องขนาดเริ่มจากศูนย์โดยธรรมชาติ

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

คอลัมน์ทำหน้าที่ชนิดเข้ารหัสด้วยจำนวนค่าที่เหมาะหมายเหตุ
provinceเขตพื้นที่เชิงพื้นที่x10–80 จุดต้องมีพิกัดกึ่งกลาง
region
ไม่บังคับ
ภูมิภาคหมวดหมู่color4–8 กลุ่มใช้สีบอกกลุ่มได้
rateปริมาณตัวเลขต่อเนื่องsizeบวกเท่านั้น★ ใช้จำนวนนับได้ ต่างจาก choropleth

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

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

ค่าที่หายไป — เขตที่ไม่มีข้อมูลไม่ควรวาดวง และต้องระบุจำนวนที่หายไปในคำอธิบาย

สเกลของแกน — พื้นที่วงแปรตรงกับค่า ซึ่งแปลว่ารัศมีแปรตามรากที่สอง และวงใหญ่ที่สุดไม่ควรกว้างเกินหนึ่งในหกของภาพ

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

เกิน 100 จุด หรือจุดกระจุกกันจนวงซ้อนทับหมด

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

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

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

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

  • จุดที่มีปริมาณมากที่สุด
  • การกระจุกตัวของปริมาณในบางภูมิภาค
  • บริเวณที่มีวงใหญ่อยู่ใกล้กันหลายวง

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

  • ★ เทียบขนาดวงให้แม่นไม่ได้ คนประเมินพื้นที่วงกลมต่ำกว่าความจริงเสมอ
  • อ่านค่าของวงที่ถูกวงใหญ่บังไม่ได้

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

  1. อ่านคำอธิบายขนาดก่อนว่าวงขนาดไหนแทนค่าเท่าไร
  2. มองหาวงใหญ่ที่สุดซึ่งคือจุดที่มีปริมาณมากสุด
  3. ดูว่าวงใหญ่กระจุกกันที่บริเวณไหน

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

  • ที่ไหนมีปริมาณมากที่สุด
  • ปริมาณกระจุกอยู่ในภูมิภาคไหน
  • จุดใหญ่ที่สุดใหญ่กว่าจุดรองแค่ไหน

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

  • ใช้รัศมีแปรตรงกับค่าแทนรากที่สอง
  • ไม่มีคำอธิบายขนาด
  • วงซ้อนกันจนวงเล็กหายไปหมด

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

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

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

  1. ★ ใส่คำอธิบายขนาดแบบวงซ้อนสามขนาดพร้อมค่ากำกับ
  2. ติดค่าเฉพาะวงที่ใหญ่ที่สุดสามถึงห้าวง
  3. ใช้ความโปร่งใสประมาณเจ็ดสิบเปอร์เซ็นต์เพื่อให้เห็นวงที่ซ้อน

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

<ตัวชี้วัด> รายจังหวัด โดย <จังหวัด> มากที่สุดที่ <ค่า>

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

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

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

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

df = pd.read_csv("graduated-symbol-map-sample.csv")
df["rate"] = pd.to_numeric(df["rate"], errors="coerce")
NOTE = "sqrt"   # ← ค่าจาก Playground

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

gdf = gpd.read_file("provinces.geojson").merge(df, on="province")
gdf["geometry"] = gdf.centroid
gdf = gdf.sort_values("rate", ascending=False)           # วาดวงใหญ่ก่อน
base = gpd.read_file("provinces.geojson")
base.plot(ax=ax, facecolor="#f2f1ed", edgecolor="#e2e0da", linewidth=0.5)
ax.scatter(gdf.geometry.x, gdf.geometry.y,
           s=np.sqrt(gdf["rate"]) * 60,                  # รากที่สอง → พื้นที่แปรตามค่า
           color=C1, alpha=0.7, edgecolor="#fcfcfb", linewidth=1.2)
ax.set_axis_off()

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

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

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

ข้อมูลตัวอย่าง · 16 แถว · seed 331● คำนวณใหม่ในเบราว์เซอร์ทันทีที่ปรับค่า
รัศมีแปรตามรากที่สอง
กรุงเทพฯกรุงเทพฯ · 26.6เชียงใหม่เชียงใหม่ · 34.7ขอนแก่นขอนแก่น · 32.7ชลบุรีชลบุรี · 34.4ภูเก็ตภูเก็ต · 26.8นครราชสีมานครราชสีมา · 18.3สงขลาสงขลา · 10.4อุดรธานีอุดรธานี · 23.1สุราษฎร์ธานีสุราษฎร์ธานี · 20.1พิษณุโลกพิษณุโลก · 17.9ระยองระยอง · 17.4นครปฐมนครปฐม · 10.5ขนาดวง (พื้นที่แปรตามค่า)8.6820.834.7

วงที่อยู่ใกล้กันทับกันได้ — วาดวงเล็กทับวงใหญ่เสมอ ไม่อย่างนั้นข้อมูลจะหาย

วงใหญ่ที่สุดเชียงใหม่
จำนวนจุด12
ค่ารวม273
ดูข้อมูลเป็นตาราง (12 แถว)
แผนที่สัญลักษณ์ 12 จุด
จังหวัดค่า
กรุงเทพฯ26.6
เชียงใหม่34.7
ขอนแก่น32.7
ชลบุรี34.4
ภูเก็ต26.8
นครราชสีมา18.3
สงขลา10.4
อุดรธานี23.1
สุราษฎร์ธานี20.1
พิษณุโลก17.9
ระยอง17.4
นครปฐม10.5

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

  • สังเกตอะไร: วงที่มีค่าเป็นสองเท่ามีพื้นที่เป็นสองเท่า ไม่ใช่รัศมีเป็นสองเท่า — ถ้าทำผิดข้อนี้ ภาพจะโกหกอย่างรุนแรง

ข้อควรระวัง

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

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

  • ข้อมูลเป็นอัตราส่วนที่ผูกกับเขตอยู่แล้วใช้แทน: choropleth-map
  • จุดหนาแน่นจนวงซ้อนกันหมดใช้แทน: hexbin-map หรือ kernel-heat-map
  • ต้องเทียบค่าให้แม่นใช้แทน: horizontal-bar เรียงตามค่า

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

เทคนิคถัดไป · แผนที่จุดความหนาแน่น