เมื่อต้องการให้ Legend Key หลายรูปแบบ (เช่น เส้นและจุด) แสดงใน Legend Entry เดียวกัน ใช้ HandlerTuple จาก matplotlib.legend_handler ร่วมกับการจัดกลุ่ม Artist เป็น Tuple
หลักการ
- Plot เส้น/จุดแยกกันได้ Artist หลายตัว
- จัดกลุ่ม Artist ที่ต้องการให้อยู่ Entry เดียวเป็น Tuple:
(artist1, artist2) - ใช้
handler_map={tuple: HandlerTuple(ndivide=None)}เพื่อบอก Legend ให้วาด Key ทั้งคู่ใน Entry เดียว
ตัวอย่างโค้ด
import matplotlib.pyplot as plt
from matplotlib.legend_handler import HandlerTuple
plt.rcParams["figure.figsize"] = [10, 6]
plt.rcParams["figure.autolayout"] = True
# สร้างข้อมูล
x = np.linspace(0, 10, 50)
y1 = np.sin(x)
y2 = np.cos(x)
fig, ax = plt.subplots()
# Plot 2 เส้น แยก Artist
line1, = ax.plot(x, y1, 'r-', linewidth=2, label='_nolegend_')
line2, = ax.plot(x, y2, 'b--', linewidth=2, label='_nolegend_')
# Plot จุดสำหรับ Legend (Optional)
scatter1 = ax.scatter(x[::5], y1[::5], c='r', s=50, zorder=5, label='_nolegend_')
scatter2 = ax.scatter(x[::5], y2[::5], c='b', s=50, marker='s', zorder=5, label='_nolegend_')
# สร้าง Legend: จัดกลุ่ม (line1, scatter1) และ (line2, scatter2) เป็น Entry เดียว
legend = ax.legend(
[(line1, scatter1), (line2, scatter2)], # List of Tuples
['Sine Wave (sin)', 'Cosine Wave (cos)'],
handler_map={tuple: HandlerTuple(ndivide=None)}, # สำคัญ!
loc='upper right',
fontsize=12,
framealpha=0.9
)
ax.set_xlabel('X', fontsize=12)
ax.set_ylabel('Y', fontsize=12)
ax.set_title('Multiple Legend Keys per Entry', fontsize=14)
ax.grid(True, alpha=0.3)
plt.show()
ผลลัพธ์
Legend แสดง 2 Entry แต่ละ Entry มี Key 2 อัน: เส้น + จุด (Circle สำหรับ Sine, Square สำหรับ Cosine) แสดงในแถวเดียวกัน
ตัวเลือก HandlerTuple
ndivide=None: วาด Key ทั้งหมดในพื้นที่เดียว (Default)ndivide=2: แบ่งพื้นที่ Key เป็น 2 ส่วน (วาดซ้อนกันไม่ได้)pad: ระยะห่างระหว่าง Keys
วิธีอื่น: ใช้ HandlerLine2D สำหรับเส้นหลายสไตล์
from matplotlib.legend_handler import HandlerLine2D
# สร้างเส้นเดียวแต่มีสไตล์หลายอย่าง (Dash + Solid)
line, = ax.plot(x, y1, 'r-', linewidth=2)
line.set_dashes([5, 2, 1, 2]) # Custom dash pattern
# Handler แสดงหลายสไตล์ใน Key เดียว
class MultiStyleHandler(HandlerLine2D):
def create_artists(self, legend, orig_handle, xdescent, ydescent, width, height, fontsize, trans):
return super().create_artists(legend, orig_handle, xdescent, ydescent, width, height, fontsize, trans)
# ใช้งาน
ax.legend([line], ['Multi-style Line'], handler_map={line: MultiStyleHandler()})
คำแนะนำ
- ใช้
label='_nolegend_'เพื่อไม่ให้ Artist ตัวนั้นปรากฏใน Legend อัตโนมัติ HandlerTupleเหมาะสำหรับรวม Marker + Line, หรือ Line + Fill- สำหรับกรณีซับซ้อน ให้สร้าง Custom Handler โดยสืบทอดจาก
HandlerBase