Skip to content

Matplotlib savefig 사용법: 레이블 잘림, bbox_inches, DPI 해결

게시일

업데이트

plt.savefig와 fig.savefig 실전 가이드입니다. bbox_inches='tight'로 레이블 잘림을 고치고 DPI, PNG/SVG/PDF, plt.show() 뒤 빈 이미지 문제를 확인합니다.

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
  • 길거나 회전된 눈금 레이블
  • 빽빽한 서브플롯 그리드

예시:

matplotlib-savefig-label-clipping-example

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")

예시:

matplotlib-constrained-layout-example.png

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 값을 점점 키워가며 조정하면 됩니다.

matplotlib-subplots-adjust-margins.png


✅ 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")

언제 쓰면 좋은가?

  • 레이아웃 코드를 건드리지 않고 빠르게 문제를 해결하고 싶을 때
  • 화면에 보이는 내용이 그대로 파일에도 들어가도록 보장하고 싶을 때

matplotlib-tight-layout-subplots.png


✅ 5. rcParams로 자동 레이아웃 활성화

모든 플롯에 공통으로 적용되는 영구적인 기본 설정을 원한다면:

matplotlib-bbox-inches-tight-example.png

런타임에 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입니다.

PyGWalker for Data visualization (opens in a new tab)

사용 방법은 간단합니다.

pip install pygwalker
import pygwalker as pyg
gwalker = pyg.walk(df)

또는 온라인에서 바로 사용해 볼 수도 있습니다.

KaggleGoogle ColabGitHub

자주 묻는 질문

  1. plt.savefig에서 레이블이 잘릴 때 어떻게 고치나요? plt.savefig("plot.png", dpi=300, bbox_inches="tight")를 먼저 사용해 보세요. 새 figure를 만드는 코드라면 plt.subplots(layout="constrained")가 더 안정적입니다.

  2. bbox_inches="tight"는 무엇을 하나요? 저장할 영역을 다시 계산해서 축 레이블, 제목, 범례, 주석이 이미지 밖으로 잘리지 않게 포함합니다.

  3. layout="constrained"bbox_inches='tight'는 어떻게 다르나요? layout="constrained"는 figure 생성 단계에서 공간을 조정하고, bbox_inches='tight'는 저장 단계에서 잘라낼 영역을 조정합니다.

  4. plt.show() 뒤에 저장하면 왜 빈 이미지가 나오나요? 일부 백엔드는 plt.show() 후 figure를 닫습니다. fig.savefig(...) 또는 plt.savefig(...)를 먼저 호출한 뒤 plt.show()를 호출하세요.

  5. savefig에 어떤 DPI를 써야 하나요? 웹과 발표 자료는 150 DPI, 보고서와 인쇄물은 300 DPI를 권장합니다. 확대 품질이 중요하면 SVG/PDF를 사용하세요.

관련 가이드