01ภาพรวมของกราฟนี้
UpSet plot แก้ข้อจำกัดของแผนภาพเวนน์ที่รองรับได้แค่สามเซต ด้วยการเลิกใช้เรขาคณิตแล้วเปลี่ยนเป็นกราฟแท่งของทุกชุดค่าผสม โดยมีเมทริกซ์จุดด้านล่างบอกว่าแท่งนั้นหมายถึงเซตไหนรวมกัน จึงรองรับได้สิบเซตขึ้นไป
เปรียบเทียบให้เห็นภาพ
เหมือนเปลี่ยนจากการวาดวงกลมทับกันมาเป็นตารางเช็คลิสต์ที่บอกว่าแต่ละกลุ่มติ๊กช่องไหนบ้าง แล้ววาดแท่งบอกว่ากลุ่มนั้นมีกี่คน
ใช้ที่ไหนบ้าง — วิเคราะห์ว่าผู้ใช้ใช้ฟีเจอร์ชุดไหนพร้อมกัน เปรียบเทียบยีนที่พบร่วมกันในหลายกลุ่ม หรือทุกกรณีที่มีเซตเกินสาม
สร้างอย่างไร
- ขั้นที่ 1นับสมาชิกในทุกชุดค่าผสมของเซต
- ขั้นที่ 2เรียงชุดค่าผสมจากมากไปน้อย
- ขั้นที่ 3วาดกราฟแท่งด้านบน
- ขั้นที่ 4วาดเมทริกซ์จุดด้านล่างที่บอกว่าแท่งนั้นคือเซตไหนรวมกัน
ตัวอย่างคลาสสิก · Lex และคณะเสนอ UpSet ในปี 2014
ทีมวิจัยชี้ว่าแผนภาพเวนน์ล้มเหลวเมื่อเกินสามเซต ซึ่งเป็นสถานการณ์ปกติในงานชีวสารสนเทศที่ต้องเทียบยีนของหลายกลุ่ม พวกเขาเสนอให้เลิกใช้เรขาคณิตแล้วกลับไปใช้กราฟแท่งที่อ่านแม่นที่สุด โดยมีเมทริกซ์จุดทำหน้าที่เป็นป้ายกำกับ
02อธิบายภาษาคนเข้าใจง่าย ๆ
เมื่อมีสี่เซตขึ้นไป แผนภาพเวนน์ต้องใช้วงรีบิดเบี้ยวและบางบริเวณเล็กจนเขียนตัวเลขไม่ได้ ที่แย่กว่านั้นคือผู้อ่านหาบริเวณที่ต้องการไม่เจอ
UpSet plot แก้ด้วยการเลิกใช้เรขาคณิตไปเลย แล้วเปลี่ยนคำถามเป็น "แต่ละชุดค่าผสมมีสมาชิกกี่คน" ซึ่งตอบด้วยกราฟแท่งธรรมดาที่อ่านแม่นที่สุด
ส่วนที่บอกว่าแท่งไหนหมายถึงอะไรคือเมทริกซ์จุดด้านล่าง แต่ละคอลัมน์ตรงกับแท่งหนึ่ง และจุดทึบบอกว่าชุดนั้นรวมเซตไหนบ้าง มีเส้นเชื่อมจุดเพื่อให้ตามง่าย
ผลที่ได้คือความสามารถที่เวนน์ไม่มีเลย คือรองรับสิบเซตได้สบาย และเรียงชุดค่าผสมจากมากไปน้อยได้ ทำให้เห็นทันทีว่าชุดไหนพบบ่อยที่สุด
ราคาที่จ่ายคือความเป็นธรรมชาติ ผู้อ่านต้องเรียนรู้วิธีอ่านเมทริกซ์จุดก่อน ซึ่งต่างจากเวนน์ที่เข้าใจได้ทันที จึงเหมาะกับงานวิเคราะห์มากกว่างานสื่อสารทั่วไป
03ข้อมูลที่ต้องใช้
คอลัมน์ที่ต้องเตรียม
| คอลัมน์ | ทำหน้าที่ | ชนิด | เข้ารหัสด้วย | จำนวนค่าที่เหมาะ | หมายเหตุ |
|---|---|---|---|---|---|
id | รหัสสมาชิก | หมวดหมู่ | text | หนึ่งแถวหนึ่งสมาชิก | ใช้ระบุว่าแต่ละคนอยู่ในเซตไหนบ้าง |
แอป | อยู่ในเซตนี้หรือไม่ | หมวดหมู่ | row | 0 หรือ 1 | หนึ่งคอลัมน์ต่อหนึ่งเซต รองรับได้ถึง 10 เซตขึ้นไป |
ต้องเตรียมข้อมูลอย่างไรก่อนวาด
- แปลงเป็นคอลัมน์ศูนย์หรือหนึ่งต่อหนึ่งเซต
- นับสมาชิกในทุกชุดค่าผสมที่พบจริง
- เรียงชุดค่าผสมจากมากไปน้อยและตัดเหลือ 10-20 ชุดแรก
ค่าที่หายไป — สมาชิกที่ไม่รู้สถานะของเซตใดต้องแยกออกและรายงาน เพราะจะทำให้จัดเข้าชุดค่าผสมผิด
สเกลของแกน — แกนของกราฟแท่งเป็น linear เริ่มที่ศูนย์ตามกฎของกราฟแท่ง
กราฟจะเริ่มพังเมื่อไร
เกิน 15 เซต จำนวนชุดค่าผสมที่เป็นไปได้จะมากจนต้องตัดเหลือเฉพาะชุดที่พบบ่อย
หน้าตาไฟล์ที่ต้องเตรียม
id,แอป,เว็บ,หน้าร้าน
user-001,0,1,0
user-002,1,0,0
…04อ่านแล้วเห็นอะไร
สิ่งที่เห็นได้จากภาพ
- ชุดค่าผสมที่พบบ่อยที่สุด
- ว่าคนส่วนใหญ่อยู่ในเซตเดียวหรือหลายเซต
- ชุดค่าผสมที่คาดว่าจะมีแต่กลับไม่มีเลย
สิ่งที่กราฟนี้ตอบไม่ได้
- ไม่สื่อแนวคิดการทับซ้อนได้ทันทีเหมือนแผนภาพเวนน์
- ต้องเรียนรู้วิธีอ่านเมทริกซ์จุดก่อน
อ่านตามลำดับนี้
- ดูแท่งที่สูงที่สุดก่อน
- ลากสายตาลงไปที่เมทริกซ์จุดใต้แท่งนั้นเพื่อดูว่าคือเซตไหนรวมกัน
- เทียบความสูงของแท่งอื่น
คำถามที่ตอบได้
- คนส่วนใหญ่ใช้ช่องทางชุดไหน
- มีกี่คนที่ใช้ทุกช่องทาง
- ชุดค่าผสมไหนที่ไม่เกิดขึ้นเลย
สัญญาณว่ามีอะไรผิด
- ไม่มีเส้นเชื่อมจุดในเมทริกซ์ ทำให้ตามยากเมื่อมีหลายเซต
- ไม่เรียงชุดค่าผสมตามขนาด
05เหมาะกับการนำเสนอแบบไหน
ทำอย่างไรให้คนอ่านได้ข้อสรุปโดยไม่ต้องบรรยาย
- เขียนตัวเลขบนทุกแท่ง
- ลากเส้นเชื่อมจุดในเมทริกซ์ให้ชัด
- แสดงขนาดรวมของแต่ละเซตไว้ด้านซ้ายของเมทริกซ์
รูปแบบชื่อกราฟที่ควรใช้
ชุดค่าผสมที่พบบ่อยที่สุดคือ <ชุด> ที่ <จำนวน> คน
06เอาไปใช้ต่อ
โค้ดทุกชิ้นอ่านไฟล์ upset-plot-sample.csv ชุดเดียวกับที่ Playground ใช้ และตัวเลขในโค้ดเปลี่ยนตามค่าที่คุณปรับด้านล่าง
# ติดตั้ง: pip install "matplotlib==3.10.*" "pandas==2.*"
# ดาวน์โหลด upset-plot-sample.csv จากหน้านี้ แล้ววางไว้ข้างสคริปต์
import matplotlib
matplotlib.use("Agg") # รันแบบไม่มีหน้าจอ ถ้ารันในเครื่องตัวเองลบบรรทัดนี้ได้
import matplotlib.pyplot as plt
import pandas as pd
from upsetplot import from_indicators, UpSet # pip install upsetplot
C1, C2, C3 = "#2a78d6", "#eb6834", "#1baf7a" # palette ของคลัง เปลี่ยนเป็นสีองค์กรได้
INK, SURFACE = "#0b0b0b", "#fcfcfb"
df = pd.read_csv("upset-plot-sample.csv")
df["แอป"] = pd.to_numeric(df["แอป"], errors="coerce")
df["เว็บ"] = pd.to_numeric(df["เว็บ"], errors="coerce")
df["หน้าร้าน"] = pd.to_numeric(df["หน้าร้าน"], errors="coerce")
NOTE = "matrix" # ← ค่าจาก Playground
fig, ax = plt.subplots(figsize=(7.6, 4.2), facecolor=SURFACE)
ax.set_facecolor(SURFACE)
fig.clf()
sets = ["แอป", "เว็บ", "หน้าร้าน"]
data = from_indicators(sets, df[sets].astype(bool))
UpSet(data, sort_by="cardinality", show_counts=True, # เรียงจากมากไปน้อย
facecolor=C1).plot(fig=fig)
fig.savefig("upset-plot.png", dpi=160)
print("เขียน upset-plot.png แล้ว")
raise SystemExit # upsetplot จัดการ figure เอง
ax.spines[["top", "right"]].set_visible(False) # ลดเส้นที่ไม่ได้ให้ข้อมูล
fig.tight_layout()
fig.savefig("upset-plot.png", dpi=160)
print("เขียน upset-plot.png แล้ว ·", len(df), "แถว")07ลองเล่นเพื่อเข้าใจ
ดูข้อมูลเป็นตาราง (7 แถว)
| ชุดค่าผสม | จำนวน |
|---|---|
| แอป | 45 |
| แอป และ เว็บ | 45 |
| เว็บ | 24 |
| แอป และ เว็บ และ หน้าร้าน | 23 |
| แอป และ หน้าร้าน | 23 |
| เว็บ และ หน้าร้าน | 11 |
| หน้าร้าน | 9 |
ลองแล้วจะเห็นอะไร
- สังเกตอะไร: ดูแท่งที่สูงที่สุดแล้วลากสายตาลงไปที่จุด จะเห็นว่าอ่านชุดค่าผสมได้ตรงและรองรับเซตได้มากกว่าแผนภาพเวนน์มาก
ข้อควรระวัง
- ไม่ลากเส้นเชื่อมจุดในเมทริกซ์ ทำให้ตามชุดค่าผสมยากเมื่อมีหลายเซต
- ไม่เรียงชุดค่าผสมตามขนาด ทำให้เสียจุดแข็งที่สำคัญที่สุด
- ใช้กับสองสามเซต ซึ่งแผนภาพเวนน์สื่อสารได้ดีกว่า
- ไม่แสดงขนาดรวมของแต่ละเซต ทำให้ไม่รู้ว่าแต่ละเซตใหญ่แค่ไหน
เมื่อไหร่ไม่ควรใช้กราฟนี้
- มีไม่เกิน 3 เซตและผู้อ่านเป็นคนทั่วไป→ใช้แทน: venn-diagram
- ต้องการสื่อแนวคิดการทับซ้อนอย่างรวดเร็ว→ใช้แทน: venn-diagram
- สนใจสัดส่วนมากกว่าจำนวน→ใช้แทน: percent-stacked-bar