Axes 하나를 발표 수준으로 다듬는 작업은 범위(set_xlim)·라벨(set_xlabel)·제목(set_title), 스케일(set_xscale('log')), 눈금(tick)과 눈금 포맷, 범례(legend) 네 가지로 나뉩니다.
눈금 위치는 Locator, 눈금 표시 문자열은 Formatter가 담당하며, MaxNLocator·FuncFormatter로 세밀하게 제어합니다.
서로 다른 단위의 두 지표를 한 그림에 겹치는 twinx()(이중 축)는 상관 착시를 일으키기 쉬워 신중해야 합니다.
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
import numpy as npfig, ax = plt.subplots()
ax.plot(np.linspace(0, 10, 100), np.linspace(0, 10, 100) ** 2)
ax.set_xlim(0, 10)
ax.set_ylim(bottom=0)
ax.set_xlabel("time (s)")
ax.set_ylabel("distance (m)")
ax.set_title("Fall distance over time")
ax.set(xlabel="time (s)", ylabel="distance (m)", title="...") # 한 번에set_ 접두사가 규칙입니다. 여러 속성은 ax.set(...)으로 묶어 지정할 수 있습니다.ax.grid(True, alpha=0.3)로 격자를 옅게 넣으면 값 읽기가 쉬워집니다.x = np.linspace(1, 1000, 500)
fig, ax = plt.subplots()
ax.plot(x, x ** 2)
ax.set_yscale("log") # y축을 로그 스케일로
# ax.set_xscale("log")
# ax.set_yscale("symlog") # 0과 음수를 포함하는 로그"log"는 에러 또는 값 누락이 나므로 "symlog"(선형+로그 혼합)를 씁니다.💡 이럴 때: 데이터가 몇 개 큰 값에 눌려 나머지가 바닥에 깔려 보이면 y축 로그 스케일을 먼저 시도합니다. 단, 막대그래프는 로그축과 궁합이 나쁩니다(길이 비교가 왜곡됨). → 데이터 전처리·시각화 이론 학습 로드맵 2.6
논의 계층을 나눕니다. 눈금은 "어디에 찍을지"(Locator)와 "어떻게 쓸지"(Formatter)가 분리되어 있습니다.
fig, ax = plt.subplots()
ax.plot(np.arange(2000, 2027), np.random.default_rng(0).normal(size=27).cumsum())
# 위치: 최대 6개, 정수 위치 선호
ax.xaxis.set_major_locator(mticker.MaxNLocator(nbins=6, integer=True))
# 표시 문자열: 천 단위 콤마
ax.yaxis.set_major_formatter(mticker.FuncFormatter(lambda v, pos: f"{v:,.0f}"))
# 보조 눈금
ax.yaxis.set_minor_locator(mticker.AutoMinorLocator())
ax.tick_params(axis="x", rotation=45)간단한 경우엔 ax.set_xticks([...]), ax.set_xticks([...], labels=[...])로 직접 지정합니다.
ticklabel_formatax.ticklabel_format(style="plain", axis="y") # 지수표기(1e6) 끄기
ax.ticklabel_format(style="sci", scilimits=(0, 0)) # 강제 지수표기💡 이럴 때: 축에
1e7같은 지수 표기나+2.024e3같은 오프셋이 떠서 헷갈리면ax.ticklabel_format(style="plain")또는FuncFormatter로 실제 값을 그대로 씁니다.
💡 이럴 때: 날짜축이 겹쳐 읽히면 matplotlib.dates의 AutoDateLocator/ConciseDateFormatter를 쓰거나 fig.autofmt_xdate()로 라벨을 기울입니다.
fig, ax = plt.subplots()
ax.plot([0, 1, 2], [0, 1, 4], label="quadratic")
ax.plot([0, 1, 2], [0, 1, 2], label="linear")
ax.legend(loc="upper left")label=을 주면 ax.legend()가 자동 수집합니다. 라벨 없는 Artist는 범례에서 빠집니다.ax.legend([artist1, artist2], ["A", "B"]).loc 값: "best"(기본, 겹침 최소 위치 자동), "upper right", "lower center" 등.ax.legend(loc="upper left", bbox_to_anchor=(1.02, 1), borderaxespad=0)
fig.tight_layout() # 또는 constrained_layoutbbox_to_anchor는 Axes 좌표(0~1) 기준 기준점입니다. (1.02, 1)은 "Axes 오른쪽 바깥, 위 정렬".fig.legend(...)로 Figure 수준에 하나만 둡니다.💡 이럴 때: 범례가 데이터를 가리면
loc="best"로 두거나, 계열이 많을 때는 그림 밖(bbox_to_anchor)으로 빼고ncol=로 여러 열로 나눕니다.
twinx() -쓰기 전 경고twinx()는 x축을 공유하고 y축이 다른 Axes를 겹쳐 만듭니다.
fig, ax1 = plt.subplots()
ax1.plot(months, revenue, color="C0")
ax1.set_ylabel("revenue", color="C0")
ax2 = ax1.twinx()
ax2.plot(months, temperature, color="C1")
ax2.set_ylabel("temperature", color="C1")위험:
두 y축의 스케일과 0 위치를 임의로 맞추면, 실제로 무관한 두 계열이 "같이 움직이는 것처럼" 보입니다(상관 착시).
어느 선이 어느 축인지 즉시 읽기 어렵습니다. 대안:
위아래로 나눈 subplots(2, 1, sharex=True) -대개 이쪽이 더 정직합니다.
두 계열을 각각 정규화(예: 첫 값=100 지수)해 하나의 축에 그리기.
💡 이럴 때: "두 지표의 추세가 비슷한지"만 보고 싶다면
twinx대신 각 계열을 지수화(첫 값 기준 %)해 한 축에 겹칩니다. 축 눈금 조작으로 만든 유사성은 근거가 되지 않습니다. → 데이터 전처리·시각화 이론 학습 로드맵 2.6
댓글
GitHub 계정으로 의견이나 질문을 남길 수 있습니다.