Matplotlib 세컨더리 축: twinx vs secondary_yaxis 완전 가이드
Updated on
한 플롯에 두 스케일이 필요할 때(달러 vs 개수, 섭씨 vs 화씨), 축을 잘못 추가하면 추세가 왜곡됩니다. 눈금이 어긋나거나 범례가 맞지 않거나 라벨이 잘리는 문제가 흔합니다. 올바른 도구를 고르고 명확한 변환을 넣어야 두 스케일이 신뢰성을 유지합니다.
빠른 선택 가이드
| 접근 | 언제 사용 | 장점 | 주의 |
|---|---|---|---|
twinx / twiny | x(또는 y) 위치만 공유하는 별도 시리즈를 겹칠 때 | 간단하고 빠름 | 눈금 포맷 수동, 스케일 자동 동기화 없음 |
secondary_yaxis / secondary_xaxis | 두 시리즈가 변환 가능할 때(예: °C ↔ °F) | 순/역 함수로 눈금 정렬 보장 | 정확한 변환 필요, 단조 변환만 |
| 공유 축 서브플롯 2개 | 겹치지 않고 비교하고 싶을 때 | 시각적으로 명확 | 공간 추가 필요, 범례 분리 |
레시피: twinx로 두 y축
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(1, 13)
sales = np.array([12, 18, 25, 30, 28, 35, 40, 38, 32, 28, 22, 18])
customers = np.array([120, 155, 180, 210, 205, 230, 245, 240, 225, 200, 175, 150])
fig, ax = plt.subplots(figsize=(8, 4))
ax.plot(x, sales, color="tab:blue", label="Sales (k$)")
ax.set_xlabel("Month")
ax.set_ylabel("Sales (k$)", color="tab:blue")
ax.tick_params(axis="y", labelcolor="tab:blue")
ax2 = ax.twinx()
ax2.plot(x, customers, color="tab:orange", label="Customers")
ax2.set_ylabel("Customers", color="tab:orange")
ax2.tick_params(axis="y", labelcolor="tab:orange")
lines = ax.get_lines() + ax2.get_lines()
labels = [line.get_label() for line in lines]
ax.legend(lines, labels, loc="upper left")
plt.tight_layout()
plt.show()팁:
- 축별로 색을 달리해 범례 혼동을 막는다.
- 두 축의 라인을 합쳐서
legend를 호출한다. tight_layout()또는constrained_layout=True로 라벨 잘림을 방지한다.
레시피: secondary_yaxis로 안전한 변환
import matplotlib.pyplot as plt
import numpy as np
temps_c = np.linspace(-20, 40, 200)
fig, ax = plt.subplots(figsize=(7, 4))
ax.plot(temps_c, np.sin(temps_c / 10), color="tab:blue", label="Signal vs °C")
ax.set_xlabel("Temperature (°C)")
ax.set_ylabel("Signal")
def c_to_f(c):
return c * 9/5 + 32
def f_to_c(f):
return (f - 32) * 5/9
ax_f = ax.secondary_xaxis("top", functions=(c_to_f, f_to_c))
ax_f.set_xlabel("Temperature (°F)")
ax.legend(loc="lower right")
plt.tight_layout()
plt.show()팁:
- 순방향/역방향 함수를 모두 지정해 눈금을 맞춘다.
- 단조롭고 역변환 가능한 변환만 사용한다.
- 눈금 포맷(
ax_f.xaxis.set_major_formatter("{x:.0f}°F"))으로 단위를 분명히 한다.
스케일을 정직하게 유지하기
- 관련 없는 시리즈라면 이중 축을 피하고 서브플롯이 더 낫다.
- 한 시리즈가 압도적이면 먼저 정규화하고 비교한다.
- 격자는 주축에만 두어 시각적 노이즈를 줄인다.
문제 해결 체크리스트
- 범례가 중복되나? 두 축 라인을 합친 뒤
legend를 호출. - 라벨이 잘리나?
constrained_layout=True또는plt.tight_layout(). - 눈금 색이 다르나? 두 축 모두
tick_params(labelcolor=...)적용.