Skip to content

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_anchorloc와 함께 사용합니다. 오른쪽에 배치: 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()를 호출하여 잘림을 방지합니다. 이중 축이 있는 복잡한 그림에서는 라인 핸들을 수동으로 결합하여 통합된 범례를 만듭니다.

📚