Matplotlib 치트시트
마지막 업데이트
figure와 axes
figure는 이미지 전체예요. axes는 그 안에 있는 그래프 하나이고, 아래 호출은 거의 모두 ax의 메서드예요.
| 작업 | 코드 |
|---|---|
| pyplot 임포트 | import matplotlib.pyplot as plt |
| 그래프 하나가 있는 figure | fig, ax = plt.subplots() |
| 크기를 인치로 지정 | fig, ax = plt.subplots(figsize=(8, 4)) |
| axes에 그리기 | ax.plot(x, y) |
| figure 표시 | plt.show() |
| 선명한 PNG로 저장 | fig.savefig("chart.png", dpi=150, bbox_inches="tight") |
| 벡터 그래픽으로 저장 | fig.savefig("chart.svg"), fig.savefig("chart.pdf") |
| 투명 배경 | fig.savefig("chart.png", transparent=True) |
| figure를 닫아 메모리 해제 | plt.close(fig) |
| 차트 하나용 간단한 pyplot 방식 | plt.plot(x, y)
plt.title("Quick look")
plt.show() |
그래프 종류
| 작업 | 코드 |
|---|---|
| 선 그래프 | ax.plot(x, y) |
| 산점도 | ax.scatter(x, y, s=20, alpha=0.7) |
| 값에 따라 색칠한 산점도와 컬러바 | points = ax.scatter(x, y, c=y, cmap="viridis")
fig.colorbar(points, ax=ax) |
| 막대 그래프 | ax.bar(cats, a) |
| 가로 막대 그래프 | ax.barh(cats, a) |
| 누적 막대 | ax.bar(cats, a, label="2025")
ax.bar(cats, b, bottom=a, label="2026") |
| 그룹 막대 | pos = np.arange(len(cats))
ax.bar(pos - 0.2, a, width=0.4)
ax.bar(pos + 0.2, b, width=0.4)
ax.set_xticks(pos, labels=cats) |
| 히스토그램 | ax.hist(data, bins=30) |
| 박스 플롯 | ax.boxplot([data, data * 2], tick_labels=["A", "B"]) |
| 바이올린 플롯 | ax.violinplot([data, data * 2]) |
| 파이 차트 | ax.pie([40, 35, 25], labels=cats, autopct="%1.0f%%") |
| 두 곡선 사이 영역 | ax.fill_between(x, y - 0.2, y + 0.2, alpha=0.3) |
| 오차 막대 | ax.errorbar([1, 2, 3], [4, 5, 3], yerr=[0.5, 0.3, 0.6], fmt="o", capsize=4) |
| 계단 그래프 | ax.step(x, y, where="mid") |
| 2D 배열 히트맵 | image = ax.imshow(np.random.default_rng(0).random((5, 5)), cmap="magma")
fig.colorbar(image, ax=ax) |
| 채운 등고선 그래프 | X, Y = np.meshgrid(x, x)
ax.contourf(X, Y, np.sin(X) * np.cos(Y), levels=20) |
| 많은 점의 밀도 | ax.hexbin(data, data + np.random.default_rng(1).normal(size=200), gridsize=20) |
| 가로 또는 세로 기준선 | ax.axhline(0, color="gray", linestyle="--"), ax.axvline(5) |
| 범위 음영 처리 | ax.axvspan(2, 4, alpha=0.2) |
선, 마커, 색상
| 작업 | 코드 |
|---|---|
| 색상, 두께, 선 스타일 | ax.plot(x, y, color="tab:red", linewidth=2, linestyle="--") |
| 점에 마커 표시 | ax.plot(x, y, marker="o", markersize=4) |
| 짧은 포맷 문자열 | ax.plot(x, y, "g--o") |
| 투명도 | ax.plot(x, y, alpha=0.5) |
| 선 스타일 종류 | "-", "--", "-.", ":" |
| 마커 코드 | "o", "s", "^", "x", ".", "*" |
| 색상 지정 방법 | "tab:blue", "C1", "#1f77b4", (0.2, 0.4, 0.6) |
| 컬러맵에서 n개 색상 | colors = plt.colormaps["viridis"](np.linspace(0, 1, 5)) |
| 나만의 색상 순환 | ax.set_prop_cycle(color=["#0b7285", "#e8590c", "#5f3dc4"]) |
| 테두리와 빗금 막대 | ax.bar(cats, a, color="white", edgecolor="black", hatch="//") |
제목, 레이블, 범례
| 작업 | 코드 |
|---|---|
| 제목과 축 레이블 | ax.set_title("Sales"), ax.set_xlabel("Month"), ax.set_ylabel("EUR") |
| 한 번의 호출로 모두 | ax.set(title="Sales", xlabel="Month", ylabel="EUR") |
| 선 레이블로 범례 만들기 | ax.plot(x, y, label="sin")
ax.legend() |
| 범례 위치와 열 수 | ax.legend(loc="upper right", ncols=2, frameon=False) |
| 그래프 밖에 범례 | ax.legend(loc="center left", bbox_to_anchor=(1, 0.5)) |
| 데이터 위치에 텍스트 | ax.text(5, 0.5, "note") |
| 화살표 주석 | ax.annotate("peak", xy=(1.57, 1), xytext=(3, 1.2), arrowprops=dict(arrowstyle="->")) |
| 막대 위 값 레이블 | bars = ax.bar(cats, a)
ax.bar_label(bars) |
| figure 전체 제목 | fig.suptitle("Q1 report") |
| 레이블에 수식 | ax.set_xlabel(r"$\alpha$ (rad)") |
축, 눈금, 스케일
| 작업 | 코드 |
|---|---|
| 축 범위 | ax.set_xlim(0, 10), ax.set_ylim(bottom=0) |
| 로그 스케일 | ax.set_yscale("log") |
| 눈금과 눈금 레이블 지정 | ax.set_xticks([0, 5, 10], labels=["start", "middle", "end"]) |
| 눈금 레이블 회전 | ax.tick_params(axis="x", labelrotation=45) |
| 격자선 | ax.grid(True, alpha=0.3) |
| 퍼센트 축 | from matplotlib.ticker import PercentFormatter
ax.yaxis.set_major_formatter(PercentFormatter(1.0)) |
| 천 단위 구분 기호 | ax.yaxis.set_major_formatter("{x:,.0f}") |
| 위쪽과 오른쪽 테두리 숨기기 | ax.spines[["top", "right"]].set_visible(False) |
| 오른쪽에 두 번째 y축 | ax2 = ax.twinx()
ax2.plot(x, y * 100, color="tab:orange") |
| 두 축을 같은 비율로 | ax.set_aspect("equal") |
| 축 뒤집기 | ax.invert_yaxis() |
| 축 완전히 숨기기 | ax.axis("off") |
| 읽기 쉬운 날짜 레이블 | fig.autofmt_xdate() |
subplots와 레이아웃
plt.subplots(rows, cols)는 axes의 NumPy 배열을 반환해요. 배열처럼 인덱싱하면 돼요.
| 작업 | 코드 |
|---|---|
| 그래프 격자 | fig, axs = plt.subplots(2, 2, figsize=(8, 6)) |
| 그중 하나에 그리기 | axs[0, 1].plot(x, y) |
| 전체를 반복하며 그리기 | for ax in axs.flat:
ax.grid(True) |
| 그래프끼리 축 공유 | fig, axs = plt.subplots(1, 3, sharey=True) |
| 겹치지 않는 간격 | fig, axs = plt.subplots(2, 2, layout="constrained") |
| 그린 뒤 겹침 해결 | fig.tight_layout() |
| 너비가 다른 열 | fig, axs = plt.subplots(1, 2, width_ratios=[3, 1]) |
| 넓은 패널이 있는 이름 기반 레이아웃 | fig, axd = plt.subplot_mosaic([["top", "top"], ["left", "right"]])
axd["top"].plot(x, y) |
| 그래프 안의 작은 그래프 | inset = ax.inset_axes([0.6, 0.6, 0.35, 0.35]) |
| 빈 패널 숨기기 | axs[0].axis("off") |
스타일과 기본값
| 작업 | 코드 |
|---|---|
| 내장 스타일 사용 | plt.style.use("ggplot") |
| 스타일 목록 보기 | plt.style.available |
| seaborn 없이 seaborn 느낌 | plt.style.use("seaborn-v0_8-whitegrid") |
| figure 하나에만 스타일 적용 | with plt.style.context("dark_background"):
fig, ax = plt.subplots() |
| 기본 글꼴 크기 | plt.rcParams["font.size"] = 12 |
| 기본 figure 크기와 해상도 | plt.rcParams["figure.figsize"] = (8, 4), plt.rcParams["figure.dpi"] = 120 |
| 기본값으로 되돌리기 | plt.style.use("default") |
| 자주 쓰는 컬러맵: 순차형, 발산형, 회색조 | "viridis", "coolwarm", "Greys" |
pandas로 그리기
pandas는 Matplotlib으로 그래프를 그려요. ax=를 넘겨 내 axes에 그리거나, pandas가 반환하는 ax를 받아 두세요.
| 작업 | 코드 |
|---|---|
| DataFrame 열을 내 axes에 | df.plot(x="month", y="sales", ax=ax) |
| 그룹 요약 막대 그래프 | df.groupby("city")["sales"].sum().plot.bar(ax=ax) |
| pandas가 그린 그래프 이어서 꾸미기 | ax = df.plot(x="month", y="sales")
ax.set_title("Sales") |
| 열을 Matplotlib에 바로 넘기기 | ax.plot(df["month"], df["sales"]) |
Matplotlib 3.11: 예전 방식과 지금 쓰는 방식
예전 튜토리얼에서 복사한 코드는 Matplotlib 3.11에서 오류나 경고가 날 수 있어요. 대신 Matplotlib 3.11 열의 방식으로 작성하세요.
| 작업 | Matplotlib 3.11 | 예전 방식 |
|---|---|---|
| 박스 플롯 레이블 | ax.boxplot([data, data * 2], tick_labels=["A", "B"]) | labels=["A", "B"] |
| 가로 박스 또는 바이올린 플롯 | ax.boxplot(data, orientation="horizontal") | vert=False |
| 컬러맵 가져오기 | plt.colormaps["viridis"] | plt.cm.get_cmap("viridis") |
| seaborn 스타일 | plt.style.use("seaborn-v0_8") | plt.style.use("seaborn") |
데이터를 깔끔한 차트로 바꾸는 데 필요한 Matplotlib 코드를 작업별로 모았어요. figure와 axes, 그래프 종류, 선과 색상, 제목과 범례, 축과 눈금, subplots와 레이아웃, 스타일, pandas로 그리기까지 담았어요. 각 행에는 바로 붙여 넣을 수 있는 짧은 코드와 무엇을 하는지 설명하는 한 줄이 있어요.
모든 예제는 객체 지향 방식(fig, ax = plt.subplots()로 만든 뒤 ax의 메서드 호출)을 쓰며, Coddy에서 실행하는 버전인 Matplotlib 3.11 기준이에요. boxplot의 labels= 같은 예전 방식은 마지막 표에만 대신 쓸 코드와 함께 나와요. 예제는 x = np.linspace(0, 10, 50), y = np.sin(x), 그리고 정규분포 값 샘플인 data를 사용해요. Python 자체가 처음이라면 Python 치트시트부터 시작하고, pandas, NumPy, scikit-learn 치트시트도 함께 띄워 두세요.
Matplotlib 치트시트 자주 묻는 질문
이 Matplotlib 치트시트는 무료인가요?
네. 이 Matplotlib 치트시트는 완전히 무료이고 가입도 필요 없어요. 북마크해 두거나 브라우저에서 PDF로 인쇄해 두고, 범례, subplot 격자, 컬러바의 정확한 호출이 필요할 때마다 다시 찾아오세요.
plt와 ax의 차이는 무엇인가요?
plt.plot()은 현재 활성화된 axes에 그리므로 차트 하나를 빠르게 그릴 때 편해요. fig, ax = plt.subplots()는 figure와 axes를 객체로 돌려주므로 ax.plot()은 항상 의도한 곳에 정확히 그려요. 그래프가 두 개 이상이거나 계속 유지할 코드라면 ax 방식을 쓰세요.figure 크기는 어떻게 바꾸나요?
figsize를 인치 단위로 넘기세요: fig, ax = plt.subplots(figsize=(10, 5)). 모든 figure의 기본값을 바꾸려면 plt.rcParams["figure.figsize"] = (10, 5)로 설정하세요. 저장한 파일의 픽셀 크기는 figsize에 dpi를 곱한 값이에요.차트를 고해상도로 저장하려면 어떻게 하나요?
fig.savefig("chart.png", dpi=300, bbox_inches="tight")를 호출하세요. dpi가 높을수록 PNG가 선명해지고, bbox_inches="tight"는 빈 여백을 잘라내요. 인쇄물이나 슬라이드용이라면 어떤 크기에서도 선명한 SVG나 PDF로 저장하세요.subplot 제목과 레이블이 왜 겹치나요?
plt.subplots(2, 2, layout="constrained")처럼 layout="constrained"로 figure를 만들면 Matplotlib이 제목, 레이블, 컬러바가 들어갈 공간을 확보해 줘요. 이미 만든 figure라면 그린 뒤에 fig.tight_layout()을 호출하세요.이 치트시트는 어떤 Matplotlib 버전을 다루나요?
boxplot의 labels=(현재는 tick_labels=)나 plt.cm.get_cmap(현재는 plt.colormaps[...])처럼 최신 버전에서 제거되거나 이름이 바뀐 호출은 마지막 표에 대신 쓸 코드와 함께 정리했어요.