팔레트·스케일·필터링, 여기까지 만지면 실전이다 – Seaborn Heatmap 번외편

Seaborn Heatmap 번외편 이미지

앞 글에서는 flights 예제 데이터로 기본 Seaborn Heatmap을 그려 보고, 색의 패턴을 읽으면서 인사이트를 정리해 봤습니다.
이번 번외편에서는 같은 데이터를 그대로 쓰지만 팔레트, 값 스케일, 연도 필터링 세 가지만 살짝 만져서 “보고용 그래프”로 한 단계 업그레이드해 보겠습니다.

실제 업무에서는

  • 팀장 · 상사에게 보여줄 메인 그래프
  • 특정 구간만 확대해서 붙이는 서브 그래프
  • 프레젠테이션에 넣을 한 장짜리 핵심 슬라이드”
    등을 만들어야 하니까요.

팔레트만 바꿔도 그래프의 성격이 달라진다

기본 히트맵은 보통 rocket류의 짙은 보라 → 밝은 노랑 팔레트를 씁니다.
하지만 “많을수록 좋다”는 메시지를 강조하고 싶다면, 직관적인 파랑–초록–노랑 계열이 훨씬 읽기 편합니다.

import matplotlib.pyplot as plt
import matplotlib.font_manager as fm
import seaborn as sns

# ===== 1) macOS 한글 폰트 탐색 =====
font_path = None
for f in fm.findSystemFonts():
    if "AppleGothic" in f or "Apple SD Gothic" in f:
        font_path = f
        break

if font_path:
    font_name = fm.FontProperties(fname=font_path).get_name()
    print("사용 폰트:", font_name)
else:
    font_name = "Apple SD Gothic Neo"
    print("AppleGothic 못찾음 →", font_name, "시도")

# ===== 2) seaborn 테마 + 폰트/마이너스 설정 =====
sns.set_theme(
    style="whitegrid",
    rc={
        "font.family": font_name,
        "axes.unicode_minus": False,
    },
)

# (추가) matplotlib에도 한 번 더 고정
plt.rcParams["font.family"] = font_name
plt.rcParams["axes.unicode_minus"] = False

# ===== 3) flights 데이터 히트맵 =====
flights_long = sns.load_dataset("flights")
flights = flights_long.pivot(index="month", columns="year", values="passengers")

fig, ax = plt.subplots(figsize=(9, 6))

sns.heatmap(
    flights,
    annot=True,
    fmt="d",
    linewidths=.5,
    cmap="YlGnBu",   # 팔레트 변경
    ax=ax,
)

ax.set_title("연도별·월별 항공 승객 수 (YlGnBu 팔레트)")
fig.tight_layout()
plt.show()
Seaborn Heatmap YlGnBu 팔레트 적용 이미지

팔레트 선택 팁

  • 매출·사용자수·승객수처럼 “커질수록 좋은 값” → YlGnBu, Greens, Blues
  • 위험도·에러 횟수처럼 “커질수록 안 좋은 값” → Reds, OrRd
  • 비율·편차처럼 양·음이 모두 중요한 값 → coolwarm, RdBu_r 같은 양·음 구분 팔레트

값 스케일 제한으로 “쏠린 색” 완화하기

연도 뒤로 갈수록 승객 수가 많이 늘어나서, 뒤쪽 연도는 거의 밝은 색만 보이고 앞쪽 연도는 어두운 색 덩어리처럼 뭉쳐 보입니다.
이럴 때는 값 스케일을 인위적으로 눌러 주거나, 로그 스케일을 살짝 사용하는 방법이 있습니다.

from matplotlib.colors import LogNorm

fig, ax = plt.subplots(figsize=(9, 6))

sns.heatmap(
    flights,
    annot=False,      # 이번엔 숫자 대신 색 패턴만 보기
    linewidths=.5,
    cmap="magma",
    norm=LogNorm(),   # 로그 스케일 적용
    ax=ax
)

ax.set_title("항공 승객 수 히트맵 (로그 스케일)")
fig.tight_layout()
항공 승객 수 히트맵 로그 스케일 이미지

로그 스케일을 쓰면

  • 뒤쪽 연도의 “압도적인 증가” 효과는 조금 줄어들고
  • 앞쪽 연도의 차이도 눈에 들어옵니다.

또는 단순하게 vmin, vmax로 상·하한을 잘라내서 극단적인 값이 그래프를 지배하지 않도록 조정할 수도 있습니다.

fig, ax = plt.subplots(figsize=(9, 6))

sns.heatmap(
    flights,
    annot=True,
    fmt="d",
    linewidths=.5,
    cmap="rocket_r",
    vmin=150,   # 최솟값 이하를 한 색으로 묶기
    vmax=600,   # 최댓값 이상을 한 색으로 묶기
    ax=ax
)

ax.set_title("항공 승객 수 히트맵 (값 범위 150~600 제한)")
fig.tight_layout()
히트맵 값 범위 제한 이미지

보고용으로는

  • 로그 스케일: 전체 패턴을 고르게 보고 싶을 때
  • vmin/vmax: “이 이상이면 다 위험”, “이 이하는 모두 양호”처럼 경계값을 강조할 때
    쓰면 좋습니다.

특정 연도만 따로 보는 “줌인 서브 히트맵”

상사에게 설명할 때는 “최근 5년만 따로 보여줄래?” 같은 요구가 나오기도 합니다.
히트맵은 열(column)이 연도이기 때문에, loc으로 필요한 연도만 골라서 그리면 됩니다.

recent_years = [1956, 1957, 1958, 1959, 1960]
flights_recent = flights[recent_years]

fig, ax = plt.subplots(figsize=(7, 5))

sns.heatmap(
    flights_recent,
    annot=True,
    fmt="d",
    linewidths=.5,
    cmap="YlOrRd",
    ax=ax
)

ax.set_title("최근 5년(1956–1960) 항공 승객 수 히트맵")
fig.tight_layout()
줌인 서브 히트맵 이미지

이렇게 만들면

  • 메인 보고서에는 전체 12년짜리 히트맵을 넣고
  • 부록이나 상세 페이지에는 “최근 5년 확대 버전”을 같이 넣어서
    “전체 패턴 + 최신 추세”를 동시에 보여줄 수 있습니다.

연도 대신 특정 월만 보고 싶다면, flights.loc["Jan":"Mar"]처럼 행 인덱스로 자르는 것도 가능합니다.

실무에서 써먹기 좋은 조합 예시

마지막으로, 위의 세 가지를 한 번에 조합해 봅니다.
“최근 5년만, 성수기(6~8월)만, 직관적인 팔레트로”라는 요구가 들어왔다고 가정해 보죠.

# 6~8월만 필터링
summer = flights.loc[["Jun", "Jul", "Aug"], 1956:1960]

fig, ax = plt.subplots(figsize=(6, 4))

sns.heatmap(
    summer,
    annot=True,
    fmt="d",
    linewidths=.5,
    cmap="YlGnBu",
    vmin=300,
    vmax=700,
    ax=ax
)

ax.set_title("성수기(6–8월) 최근 5년 승객 수 비교")
fig.tight_layout()
보고서용 그림 이미지

이 정도만 조합해도

  • “최근 5년 동안 여름 성수기 수요가 얼마나 더 커졌는지”
  • “어느 해가 유난히 강했는지”
    를 한눈에 설명할 수 있는 “보고서용 그림”이 됩니다.

마무리 – 번외편에서 챙겨야 할 것들

이번 번외편에서 정리한 포인트를 다시 적어 보면

  • 팔레트는 값의 의미(좋음/나쁨/중립)에 맞춰 고르기
  • 값 스케일은 로그 스케일 또는 vmin/vmax로 “쏠림”을 완화하기
  • 특정 연도·월을 필터링해서 메인·서브 그래프를 분리 구성하기

앞으로 실제 프로젝트에서 히트맵을 그릴 때,
“그냥 한 번에 다 보여주는 기본 그래프”에서 한 걸음 더 나아가서
“보고서와 발표를 위해 다듬어진 그래프”로 만들어 보는 연습을 해보면 좋겠습니다.

類似の投稿