Matplotlib savefig 사용법: 레이블 잘림, bbox_inches, DPI 해결
게시일
업데이트

Matplotlib에서 그림을 저장할 때는 먼저 fig.savefig("plot.png", dpi=300, bbox_inches="tight")를 확인하세요. 한국어 페이지는 긴 공식 문서보다 바로 적용할 수 있는 사용법이 더 중요하므로, 이 글은 plt.savefig, fig.savefig, bbox_inches, DPI, 빈 이미지 문제를 중심으로 정리합니다.
savefig 빠른 해결표
fig.savefig(
"plot.png",
dpi=300,
bbox_inches="tight",
pad_inches=0.1,
)| 문제 | 먼저 시도할 것 |
|---|---|
| 레이블, 제목, 범례가 잘림 | bbox_inches="tight" |
| 새로 그리는 코드 | plt.subplots(layout="constrained") |
| 저장 이미지가 비어 있음 | savefig()를 plt.show()보다 먼저 호출 |
| 바깥 여백이 너무 큼 | bbox_inches="tight", pad_inches=0 |
| 보고서용 고해상도 이미지 | dpi=300 또는 SVG/PDF |
plt.show() 뒤에 저장하면 빈 이미지가 나오는 경우
일부 환경에서는 plt.show()가 figure를 닫거나 pyplot에서 해제합니다. 그 뒤에 plt.savefig()를 호출하면 빈 figure가 저장될 수 있습니다. 저장을 먼저 하고, 표시를 나중에 하세요.
fig, ax = plt.subplots()
ax.plot([1, 2, 3], [1, 4, 9])
fig.savefig("chart.png", dpi=300, bbox_inches="tight")
plt.show()🧠 왜 이런 문제가 생길까?
Matplotlib은 레이블이 축 밖으로 튀어나가더라도 그에 맞게 figure 캔버스를 자동으로 확장하지 않습니다. 대표적인 원인은 다음과 같습니다.
- 세로로 긴 기호를 포함한 LaTeX 스타일 수식
- 큰
fontsize값 - 길거나 회전된 눈금 레이블
- 빽빽한 서브플롯 그리드
예시:

import matplotlib.pyplot as plt
plt.figure()
plt.ylabel(r'$\ln\left(\frac{x_a-x_b}{x_a-x_c}\right)$')
plt.xlabel(r'$\ln\left(\frac{x_a-x_d}{x_a-x_e}\right)$', fontsize=50)
plt.title('Example with matplotlib 3.4.2\nLabel clipping example')
plt.show()ylabel은 보이지만, 저장한 그림에서는 xlabel이 잘려 나가는 경우가 많습니다.
✅ 1. 최신 권장 해결책: layout="constrained" 사용 (추천)
현재 Matplotlib에서는 layout="constrained"를 명시하는 방식이 가장 실용적인 기본값입니다.
fig, ax = plt.subplots(layout="constrained")예시:

fig, ax = plt.subplots(figsize=(7, 5), layout="constrained")
ax.set_xlabel("Very long bottom label that usually gets clipped", fontsize=16)
ax.set_ylabel("Tall math label:\n$\\frac{x_a - x_b}{x_c}$")
fig.savefig("figure.png")✔ 장점
- 최신 방식이며 안정적
tight_layout()보다 동작이 개선됨- colorbar, legend, 여러 서브플롯과 함께 사용해도 성능이 좋음
⚠ 단점
- 서브플롯이 매우 많은 큰 그리드에서는 약간 느릴 수 있음
새로 Matplotlib 코드를 작성한다면, 이 방법을 기본값으로 사용하는 것을 권장합니다.
✅ 2. subplots_adjust로 여백을 수동 조정
여전히 간단하면서도 효과적인 방식입니다.
plt.subplots_adjust(bottom=0.15)또는 figure 객체에 대해:
plt.gcf().subplots_adjust(bottom=0.18)레이블이 겹치지 않을 때까지 margin 값을 점점 키워가며 조정하면 됩니다.

✅ 3. tight_layout() 사용 (구식이지만 여전히 유용)
tight_layout()은 패딩을 자동으로 조정해 줍니다.
fig, axes = plt.subplots(ncols=2, nrows=2, figsize=(8, 6))
for ax in axes.flatten():
ax.set_xlabel("Example X label")
ax.set_ylabel("Example Y label")
plt.tight_layout()
plt.show()참고 사항
- 단순한 플롯에 좋음
- legend, colorbar가 많을 경우 레이아웃이 꼬일 수 있음
- 현재는
layout="constrained"가 더 권장되는 방법
✅ 4. 저장 시 bbox_inches="tight" 사용 (빠른 응급처치)
레이블 잘림에 널리 쓰이는 해결책입니다.
plt.savefig("myfile.png", bbox_inches="tight")언제 쓰면 좋은가?
- 레이아웃 코드를 건드리지 않고 빠르게 문제를 해결하고 싶을 때
- 화면에 보이는 내용이 그대로 파일에도 들어가도록 보장하고 싶을 때

✅ 5. rcParams로 자동 레이아웃 활성화
모든 플롯에 공통으로 적용되는 영구적인 기본 설정을 원한다면:

런타임에 rcParams 업데이트:
from matplotlib import rcParams
rcParams.update({"figure.autolayout": True})또는 matplotlibrc 설정 파일에 추가:
figure.autolayout : True이렇게 하면 팀원이나 다른 머신에서도 일관된 출력 결과를 얻는 데 도움이 됩니다.
📌 요약 표: 어떤 방법을 언제 써야 할까?
| Method | 언제 사용할까 | 어떤 경우에 가장 적합한가 |
|---|---|---|
layout="constrained" | 기본 선택 | 최신 레이아웃, 서브플롯, legend 포함 |
bbox_inches='tight' | 저장할 때 빠르게 문제를 해결하고 싶을 때 | 단일 플롯 내보내기 |
tight_layout() | 기존(레거시) 코드 유지 보수 시 | 단순한 서브플롯 그리드 |
subplots_adjust() | 완전한 수동 제어가 필요할 때 | 출판용 미세 튜닝 |
figure.autolayout=True | 프로젝트 전체의 기본 설정으로 쓸 때 | 환경·시스템 간 결과 일관성 유지 |
💡 완성도 높은 Figure를 위한 추가 팁
✔ 긴 레이블이 있을 때는 DPI를 높여 저장
plt.savefig("fig.png", dpi=200, bbox_inches="tight")✔ 꼭 필요하지 않다면 지나치게 큰 글꼴 크기는 피하기
글꼴이 커질수록 잘림 가능성이 커집니다.
✔ colorbar가 있을 때는 constrained_layout 사용
tight_layout보다 colorbar 처리 성능이 확실히 좋습니다.
📊 수동 레이아웃 조정 없이 시각화 만들기 (PyGWalker)
DataFrame 시각화 목적이라면, Matplotlib에서 일일이 레이아웃을 손보지 않아도 될 수 있습니다.
단순히:
- DataFrame을 로드하고
- 필드를 드래그 앤 드롭한 뒤
- 바로 차트를 생성
하는 식으로 사용할 수 있습니다.
이때 활용할 수 있는 오픈소스 시각화 도구가 PyGWalker입니다.
사용 방법은 간단합니다.
pip install pygwalker
import pygwalker as pyg
gwalker = pyg.walk(df)또는 온라인에서 바로 사용해 볼 수도 있습니다.
| Kaggle | Google Colab | GitHub |
|---|---|---|
![]() | ![]() | ![]() |
자주 묻는 질문
-
plt.savefig에서 레이블이 잘릴 때 어떻게 고치나요?plt.savefig("plot.png", dpi=300, bbox_inches="tight")를 먼저 사용해 보세요. 새 figure를 만드는 코드라면plt.subplots(layout="constrained")가 더 안정적입니다. -
bbox_inches="tight"는 무엇을 하나요? 저장할 영역을 다시 계산해서 축 레이블, 제목, 범례, 주석이 이미지 밖으로 잘리지 않게 포함합니다. -
layout="constrained"와bbox_inches='tight'는 어떻게 다르나요?layout="constrained"는 figure 생성 단계에서 공간을 조정하고,bbox_inches='tight'는 저장 단계에서 잘라낼 영역을 조정합니다. -
plt.show()뒤에 저장하면 왜 빈 이미지가 나오나요? 일부 백엔드는plt.show()후 figure를 닫습니다.fig.savefig(...)또는plt.savefig(...)를 먼저 호출한 뒤plt.show()를 호출하세요. -
savefig에 어떤 DPI를 써야 하나요? 웹과 발표 자료는 150 DPI, 보고서와 인쇄물은 300 DPI를 권장합니다. 확대 품질이 중요하면 SVG/PDF를 사용하세요.
관련 가이드
- Matplotlib Subplots -- 여러 패널 figure의 레이아웃을 정리합니다.
- Matplotlib Figure Size -- inch, pixel, DPI 관계를 조정합니다.
- Matplotlib Histogram -- 제목과 레이블이 있는 히스토그램을 저장합니다.
- Seaborn Heatmap -- annotation과 colorbar가 있는 heatmap을 내보냅니다.



