Matplotlib Legend: 범례 추가 및 사용자 정의 완전 가이드
Updated on
범례가 없는 차트는 독자가 어떤 선이 무엇인지 추측하게 만듭니다. 색상을 머릿속으로 매칭하고, 데이터를 잘못 읽고, 틀린 결론을 내립니다. plt.legend()로 범례를 추가하는 것은 간단하지만 -- 어디에 나타나는지, 어떻게 보이는지, 데이터를 가리지 않게 하는 것은 대부분의 튜토리얼이 보여주는 것보다 더 많은 작업이 필요합니다.
이 가이드는 기본 범례 생성부터 고급 사용자 정의까지 모든 것을 다룹니다: 플롯 안팎의 배치, 다중 열 레이아웃, 사용자 정의 핸들, 복잡한 그림의 범례.
기본 범례
자동 라벨
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 100)
plt.plot(x, np.sin(x), label='sin(x)')
plt.plot(x, np.cos(x), label='cos(x)')
plt.legend()
plt.show()plot()의 label 매개변수가 범례에 표시되는 내용을 정의합니다. plt.legend()를 호출하여 표시합니다.
객체 지향 스타일
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 100)
fig, ax = plt.subplots(figsize=(8, 5))
ax.plot(x, np.sin(x), label='sin(x)')
ax.plot(x, np.cos(x), label='cos(x)')
ax.legend()
plt.show()범례 배치
loc 매개변수 사용
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 100)
fig, ax = plt.subplots(figsize=(8, 5))
ax.plot(x, np.sin(x), label='sin(x)')
ax.plot(x, np.cos(x), label='cos(x)')
# 일반적인 위치
ax.legend(loc='upper right') # 기본값
# ax.legend(loc='upper left')
# ax.legend(loc='lower right')
# ax.legend(loc='lower left')
# ax.legend(loc='center')
# ax.legend(loc='best') # 겹침이 가장 적은 위치를 자동 선택
plt.show()모든 loc 옵션
| loc 문자열 | loc 숫자 |
|---|---|
'best' | 0 |
'upper right' | 1 |
'upper left' | 2 |
'lower left' | 3 |
'lower right' | 4 |
'right' | 5 |
'center left' | 6 |
'center right' | 7 |
'lower center' | 8 |
'upper center' | 9 |
'center' | 10 |
bbox_to_anchor로 정밀 배치
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 100)
fig, ax = plt.subplots(figsize=(8, 5))
ax.plot(x, np.sin(x), label='sin(x)')
ax.plot(x, np.cos(x), label='cos(x)')
ax.plot(x, np.sin(x) + np.cos(x), label='sin(x) + cos(x)')
# 축 비율 좌표(x, y)에 범례 배치
ax.legend(loc='upper left', bbox_to_anchor=(0.02, 0.98))
plt.show()플롯 외부의 범례
범례가 데이터와 겹칠 때 외부로 이동합니다:
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 100)
fig, ax = plt.subplots(figsize=(10, 5))
for i in range(6):
ax.plot(x, np.sin(x + i * 0.5), label=f'Phase {i}')
# 플롯 오른쪽에 범례 배치
ax.legend(loc='center left', bbox_to_anchor=(1.0, 0.5))
plt.tight_layout()
plt.show()import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 100)
fig, ax = plt.subplots(figsize=(8, 6))
for i in range(5):
ax.plot(x, np.sin(x + i), label=f'Series {i+1}')
# 플롯 아래에 범례 배치
ax.legend(loc='upper center', bbox_to_anchor=(0.5, -0.1), ncol=5)
plt.tight_layout()
plt.show()범례 스타일링
글꼴 크기와 프레임
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 100)
fig, ax = plt.subplots(figsize=(8, 5))
ax.plot(x, np.sin(x), label='sin(x)')
ax.plot(x, np.cos(x), label='cos(x)')
ax.legend(
fontsize=12,
frameon=True, # 테두리 표시 (기본값 True)
framealpha=0.8, # 테두리 투명도
facecolor='lightyellow', # 배경색
edgecolor='gray', # 테두리 색상
shadow=True, # 그림자
)
plt.show()다중 열 레이아웃
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 100)
fig, ax = plt.subplots(figsize=(10, 5))
for i in range(8):
ax.plot(x, np.sin(x + i * 0.4), label=f'Signal {i+1}')
# 컴팩트한 범례를 위한 4열
ax.legend(ncol=4, loc='upper center', fontsize=9)
plt.show()범례 제목
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 100)
fig, ax = plt.subplots(figsize=(8, 5))
ax.plot(x, x**2, label='Quadratic')
ax.plot(x, x**1.5, label='Power 1.5')
ax.plot(x, x, label='Linear')
ax.legend(title='성장 모델', title_fontsize=13, fontsize=11)
plt.show()사용자 정의 범례 핸들
수동 범례 항목
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
import matplotlib.lines as mlines
import numpy as np
fig, ax = plt.subplots(figsize=(8, 5))
# 라벨 없이 플롯
ax.scatter(np.random.randn(50), np.random.randn(50), c='blue', s=20)
ax.scatter(np.random.randn(50) + 2, np.random.randn(50), c='red', s=20)
# 사용자 정의 핸들 생성
blue_patch = mpatches.Patch(color='blue', label='그룹 A')
red_patch = mpatches.Patch(color='red', label='그룹 B')
line_handle = mlines.Line2D([], [], color='green', linestyle='--', label='임계값')
ax.legend(handles=[blue_patch, red_patch, line_handle])
plt.show()색상 매핑이 있는 산점도 범례
import matplotlib.pyplot as plt
import numpy as np
fig, ax = plt.subplots(figsize=(8, 5))
categories = ['A', 'B', 'C']
colors = ['#e74c3c', '#3498db', '#2ecc71']
for cat, color in zip(categories, colors):
x = np.random.randn(30)
y = np.random.randn(30)
ax.scatter(x, y, c=color, label=f'카테고리 {cat}', alpha=0.7, s=50)
ax.legend()
plt.show()범례 사용자 정의 옵션
| 매개변수 | 설명 | 예시 |
|---|---|---|
loc | 위치 문자열 또는 숫자 | 'upper right', 2 |
bbox_to_anchor | 앵커 포인트 (x, y) | (1.0, 0.5) |
ncol | 열 수 | 3 |
fontsize | 텍스트 크기 | 12, 'small' |
title | 범례 제목 | 'My Legend' |
frameon | 프레임 표시 | True, False |
framealpha | 프레임 투명도 | 0.8 |
facecolor | 배경색 | 'white' |
edgecolor | 테두리 색상 | 'gray' |
shadow | 그림자 | True |
markerscale | 마커 크기 배율 | 1.5 |
labelspacing | 항목 간 수직 간격 | 0.5 |
handlelength | 범례 선 길이 | 2.0 |
실용적인 예제
여러 플롯 유형의 범례
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(5)
values = [23, 45, 56, 78, 32]
trend = [20, 35, 50, 65, 40]
fig, ax = plt.subplots(figsize=(8, 5))
ax.bar(x, values, alpha=0.7, label='실적', color='steelblue')
ax.plot(x, trend, 'ro-', label='추세', linewidth=2)
ax.axhline(y=50, color='green', linestyle='--', label='목표')
ax.legend(loc='upper left')
ax.set_xlabel('분기')
ax.set_ylabel('매출 ($K)')
plt.show()이중 축의 개별 범례
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(2020, 2027)
revenue = [100, 120, 115, 140, 160, 175, 200]
employees = [50, 55, 52, 60, 70, 75, 85]
fig, ax1 = plt.subplots(figsize=(8, 5))
line1 = ax1.plot(x, revenue, 'b-o', label='매출 ($M)')
ax1.set_ylabel('매출 ($M)', color='blue')
ax2 = ax1.twinx()
line2 = ax2.plot(x, employees, 'r-s', label='직원 수')
ax2.set_ylabel('직원 수', color='red')
# 범례 결합
lines = line1 + line2
labels = [l.get_label() for l in lines]
ax1.legend(lines, labels, loc='upper left')
plt.show()인터랙티브 데이터 탐색
차트 미학과 범례 배치를 반복적으로 조정할 때, PyGWalker (opens in a new tab)를 사용하면 Jupyter에서 열을 드래그하여 인터랙티브한 시각화를 구축할 수 있습니다 -- 범례, 색상, 크기가 자동으로 생성됩니다:
import pandas as pd
import pygwalker as pyg
df = pd.read_csv('your_data.csv')
walker = pyg.walk(df)자주 묻는 질문
Matplotlib 플롯에 범례를 추가하려면?
각 plot(), scatter(), bar() 호출에 label='name'을 추가한 다음 plt.legend() 또는 ax.legend()를 호출합니다. 범례는 제공된 라벨을 자동으로 사용합니다.
범례를 플롯 외부로 이동하려면?
bbox_to_anchor를 loc와 함께 사용합니다. 오른쪽에 배치: ax.legend(loc='center left', bbox_to_anchor=(1.0, 0.5)). 아래에 배치: ax.legend(loc='upper center', bbox_to_anchor=(0.5, -0.1)). plt.tight_layout()를 호출하여 잘림을 방지합니다.
Matplotlib에서 범례 글꼴 크기를 변경하려면?
legend()에 fontsize를 전달합니다: ax.legend(fontsize=14) 또는 'small', 'medium', 'large'와 같은 문자열 크기를 사용합니다. 제목의 경우: ax.legend(title='Title', title_fontsize=16).
다중 열 범례를 만들려면?
ncol 매개변수를 사용합니다: ax.legend(ncol=3)은 3열 레이아웃을 만듭니다. 많은 범례 항목이 있고 컴팩트한 수평 레이아웃이 필요할 때 유용합니다.
범례 테두리를 제거하려면?
frameon=False를 설정합니다: ax.legend(frameon=False). 프레임을 유지하면서 투명하게 만들려면 framealpha=0을 사용합니다: ax.legend(framealpha=0).
결론
Matplotlib 범례는 label 매개변수와 plt.legend()에서 시작합니다. 표준 위치에는 loc를, 플롯 외부로 범례를 이동하려면 bbox_to_anchor를, 다중 열 레이아웃에는 ncol을, 사용자 정의에는 fontsize, frameon, shadow 등의 스타일링 매개변수를 사용합니다. 많은 시리즈가 있는 플롯에서는 범례를 축 영역 밖에 배치하고 tight_layout()를 호출하여 잘림을 방지합니다. 이중 축이 있는 복잡한 그림에서는 라인 핸들을 수동으로 결합하여 통합된 범례를 만듭니다.