seaborn palette 완전 정복: 시각화 퀄리티를 올리는 색상 팔레트 활용법

seaborn palette 완전 정복

같은 그래프라도 어떤 색을 쓰느냐에 따라 완전히 다른 느낌을 줍니다.
海生 palette 이 색감 문제를 가장 세련되게 해결해 줄 수 있죠.
어떻게 사용하느냐에 따라 차분한 분석 리포트처럼 보일 수도 있고,
눈만 아픈 인포그래픽이 되어버릴 수도 있죠.

seaborn palette(시본 팔레트)는 말 그대로 “색상 팔레트 설정 도구”인데,
단순히 색 몇 개를 고르는 수준이 아니라,

  • 범주형 데이터에 어울리는 질적(qualitative) palette,
  • 크고 작음을 강조하는 연속형(sequential) palette,
  • 양극단(+, -) 차이를 보여주는 발산형(diverging) palette

처럼 데이터의 의미에 맞는 색 구성을 한 번에 불러올 수 있습니다.
그래서 시각화에서 가장 중요한 “색의 역할”을
시본 팔레트 하나로 크게 개선할 수 있어요.

seaborn palette가 필요한 대표적인 순간들

seaborn palette image

seaborn palette가 특히 빛나는 상황을 몇 가지로 정리해보면:

  1. 범주형 막대그래프가 “무지개 지옥”이 되었을 때
    • 카테고리가 5~8개 정도 있을 때,
      아무 색이나 섞어 쓰면 그래프가 정신없어집니다.
    • 이때 시본 팔레트에서 color_palette("Set2"), "Pastel1" 같은
      qualitative seaborn palette를 쓰면
      서로 구분은 잘 되지만 과하게 튀지 않는 색 조합을 자동으로 얻을 수 있습니다.
  2. 값의 크고 작음을 부드럽게 표현하고 싶을 때
    • 예: 매출 구간, 점수, 확률 등 연속적인 수치
    • seaborn palette"蓝调", "Greens" 같은 sequential 팔레트를 고르면
      진한 색 → 높은 값, 연한 색 → 낮은 값이라는 흐름이 자연스럽게 전달됩니다.
  3. 기준점(0)을 중심으로 양·음의 차이를 보여줄 때
    • 예: 수익 vs 손실, 평균 대비 +/– 편차
    • "coolwarm", "RdBu" 같은 diverging seaborn 팔레트를 쓰면
      0을 기준으로 양수는 따뜻한 색, 음수는 차가운 색처럼
      “어느 쪽이 더 위험/좋은 상태인지”를 직관적으로 표시할 수 있습니다.

seaborn palette의 기본 사용 흐름

실제 코드로 들어가면 보통 이런 흐름을 많이 씁니다.

  1. 팔레트 객체를 미리 만들기 import seaborn as sns palette = sns.color_palette("Set2", n_colors=6)
  2. seaborn 그래프에 직접 넘기기 sns.barplot(data=df, x="category", y="value", palette=palette)
  3. 전역 스타일로 한 번에 적용하기 sns.set_palette("Set2")

其中 핵심 포인트는 두 가지

  • 시본 팔레트는 “색 이름 문자열” 또는 “팔레트 객체” 형태로 사용할 수 있다.
  • 그래프마다 palette를 다르게 줄 수도 있고,
    sns.set_palette()전체 스타일을 한 번에 통일할 수도 있다.

그래서 실무 프로젝트에서는 프로젝트마다 “우리 브랜드 느낌”에 맞는
대표적인 시본 팔레트 세트를 먼저 정해두고,
모든 노트북·리포트에서 그 팔레트만 쓰도록 합의하는 경우도 많습니다.
이렇게 하면 여러 사람이 만든 그래프도 전체적으로 톤이 맞는 일관된 디자인을 갖게 되죠.

시본 팔레트를 잘 쓰기 위한 실무 감각

qualitative seaborn palette image
(资料来源 seaborn website)

以下是 동일한 데이터로 6가지 다른 팔레트를 적용한 실전 예시입니다.
그래프의 느낌을 보시고 취사선택하시면 됩니다.

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

# 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 테마 + rc를 같이 지정 (중요)
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

# 테스트 데이터
df = pd.DataFrame({
"유형": ["안전", "위생", "환경", "품질", "기타", "기계고장"],
"건수": [25, 12, 8, 15, 5, 30]
})

palettes = ["Set2", "Pastel1", "tab10", "Set3", "muted", "bright"]

plt.figure(figsize=(12, 8))
for i, pal in enumerate(palettes, 1):
ax = plt.subplot(2, 3, i)

sns.barplot(
data=df, x="유형", y="건수",
hue="유형", dodge=False,
palette=sns.color_palette(pal, n_colors=len(df))
)

# legend 제거 (seaborn 버전 호환)
leg = ax.get_legend()
if leg:
leg.remove()

ax.set_title(f"{pal}: 한글 완벽 테스트", fontsize=12, weight="bold")
ax.tick_params(axis="x", rotation=45)
ax.set_ylim(0, 35)

plt.tight_layout()
plt.show()
동일한 데이터로 6가지 다른 팔레트 이미지

그리고 시본 팔레트를 고를 때 기억해두면 좋은 간단한 기준을 정리해보면

  • 범주형(카테고리) → Set2, Set3, Pastel, tab10 같은 qualitative seaborn 팔레트
  • 순서를 가지는 수치 → Blues, Greens, Oranges 같은 sequential seaborn 调色板
  • 기준값 기준 +/– → coolwarm, RdBu, BrBG 같은 diverging seaborn 调色板

이 기준만 기억해도
“색을 아무렇게나 고르는 단계”에서
“데이터의 의미에 맞는 색을 선택하는 단계”로 한 단계 올라갈 수 있어요.

import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

from matplotlib.colors import Normalize, TwoSlopeNorm
from matplotlib.cm import ScalarMappable
import matplotlib as mpl

# =========================
# 0) 랜덤 데이터 생성 (재현 가능)
# =========================
rng = np.random.default_rng(42)

# -----------------------------
# 1) 범주형(category) -> 수치형(value) : 질적(qualitative) 팔레트
# -----------------------------
cats = [f"Cat {i}" for i in range(1, 9)]
df_qual = pd.DataFrame({
    "category": cats,
    "value": rng.integers(10, 60, size=len(cats))
})

# -----------------------------
# 2) 범주형(item) -> 수치형(value) : 순차(sequential) 팔레트 (값 크기 기반)
# -----------------------------
items = [f"Item {i}" for i in range(1, 11)]
vals_seq = rng.normal(loc=50, scale=12, size=len(items)).clip(10, 90)
df_seq = pd.DataFrame({"item": items, "value": vals_seq}).sort_values("value")

# -----------------------------
# 3) 범주형(metric) -> 수치형(delta) : 발산(diverging) 팔레트 (0을 중심으로 +/-)
# -----------------------------
names = [f"Metric {i}" for i in range(1, 11)]
vals_div = rng.normal(loc=0, scale=20, size=len(names)).clip(-50, 50)
df_div = pd.DataFrame({"metric": names, "delta": vals_div}).sort_values("delta")

# =========================
# 1) 그림(figure) 생성
# =========================
sns.set_theme(style="whitegrid")
fig, axes = plt.subplots(1, 3, figsize=(18, 6), constrained_layout=True)

# =========================================================
# A. 질적(qualitative) 팔레트: Set2 / Set3 / Pastel1 / tab10 등
#    ✅ Seaborn v0.14 대비: palette 사용 시 hue를 반드시 지정
# =========================================================
qual_palette_name = "Set2"  # "Set3", "Pastel1", "tab10" 등으로 바꿔도 됨
qual_colors = sns.color_palette(qual_palette_name, n_colors=len(df_qual))

sns.barplot(
    data=df_qual,
    x="category",
    y="value",
    hue="category",       # ✅ 경고 해결 핵심: x 변수를 hue로 지정
    palette=qual_colors,  # 카테고리별 색상
    legend=False,         # ✅ legend 제거(경고 해결 권장 방식)
    dodge=False,          # hue가 있지만 막대를 겹치지 않게(같은 항목 1개 막대처럼)
    ax=axes[0]
)

axes[0].set_title(f"Qualitative palette: {qual_palette_name}")
axes[0].tick_params(axis="x", rotation=45)

# =========================================================
# B. 순차(sequential) 팔레트: Blues / Greens / Oranges 등
#    - 막대 색을 '값 크기'에 따라 연하게/진하게 부여
#    ✅ Matplotlib get_cmap() deprec. 해결: mpl.colormaps.get_cmap 사용
#    ✅ Seaborn v0.14 대비: palette 사용 시 hue 지정
# =========================================================
seq_cmap_name = "Blues"  # "Greens", "Oranges" 등으로 변경 가능
seq_cmap = mpl.colormaps.get_cmap(seq_cmap_name)  # ✅ deprec 해결

# 값 범위를 [0,1]로 정규화하기 위한 설정
norm_seq = Normalize(vmin=df_seq["value"].min(), vmax=df_seq["value"].max())

# 각 값에 대응하는 RGBA 색상을 만들기
seq_colors = [seq_cmap(norm_seq(v)) for v in df_seq["value"]]

sns.barplot(
    data=df_seq,
    x="item",
    y="value",
    hue="item",           # ✅ 경고 해결: x를 hue로 지정
    palette=seq_colors,   # 값 기반으로 만든 색 리스트
    legend=False,         # ✅ 범례 제거
    dodge=False,
    ax=axes[1]
)

axes[1].set_title(f"Sequential palette: {seq_cmap_name} (by value)")
axes[1].tick_params(axis="x", rotation=45)

# 순차 팔레트 컬러바(색=값 크기)를 함께 표시
sm_seq = ScalarMappable(norm=norm_seq, cmap=seq_cmap)
sm_seq.set_array([])
cbar_seq = fig.colorbar(sm_seq, ax=axes[1], fraction=0.05, pad=0.02)
cbar_seq.set_label("Value")

# =========================================================
# C. 발산(diverging) 팔레트: coolwarm / RdBu / BrBG 등
#    - 0을 중심으로 음수/양수에 따라 색이 갈라짐
#    ✅ Matplotlib get_cmap() deprec 해결
#    ✅ Seaborn v0.14 대비: palette 사용 시 hue 지정
# =========================================================
div_cmap_name = "coolwarm"  # "RdBu", "BrBG" 등 가능
div_cmap = mpl.colormaps.get_cmap(div_cmap_name)  # ✅ deprec 해결

# 0을 중심값(vcenter)으로 두고 양/음수 색을 대칭적으로 매핑
norm_div = TwoSlopeNorm(
    vmin=df_div["delta"].min(),
    vcenter=0,
    vmax=df_div["delta"].max()
)

div_colors = [div_cmap(norm_div(v)) for v in df_div["delta"]]

sns.barplot(
    data=df_div,
    x="metric",
    y="delta",
    hue="metric",         # ✅ 경고 해결
    palette=div_colors,   # +/- 값에 따라 만든 색 리스트
    legend=False,
    dodge=False,
    ax=axes[2]
)

axes[2].axhline(0, linewidth=1)
axes[2].set_title(f"Diverging palette: {div_cmap_name} (center=0)")
axes[2].tick_params(axis="x", rotation=45)

# 발산 팔레트 컬러바(색=delta 크기)를 함께 표시
sm_div = ScalarMappable(norm=norm_div, cmap=div_cmap)
sm_div.set_array([])
cbar_div = fig.colorbar(sm_div, ax=axes[2], fraction=0.05, pad=0.02)
cbar_div.set_label("Delta (±)")

plt.show()
output image

类似文章