Skip to content

Matplotlib 컬러맵: 파이썬에서 컬러 맵을 완벽하게 다루는 가이드

Updated on

데이터 시각화에서 올바른 색을 고르는 일은 생각보다 훨씬 어렵습니다. 무지개(rainbow) 컬러맵을 고르면 히트맵이 드라마틱해 보이긴 하지만, 지각적 비균일성(perceptual non-uniformity) 때문에 데이터가 왜곡되고 시청자를 오도하며, 색각 이상(color-vision deficiency)이 있는 사람에게는 아예 읽히지 않기도 합니다. 반대로 단일 색조(single-hue) 팔레트를 쓰면 미묘한 패턴이 거의 비슷한 음영의 벽 속으로 사라져 버립니다. 인사이트를 드러내는 차트와 인사이트를 숨기는 차트의 차이는 종종 단 한 가지 결정, 즉 컬러맵(colormap) 선택에서 갈립니다.

Matplotlib에는 150개가 넘는 내장 컬러맵과, 직접 컬러맵을 만들 수 있는 유연한 API가 포함되어 있습니다. 문제는 선택지가 부족한 게 아니라, 어떤 컬러맵을 언제 써야 하는지, 그리고 내 데이터셋에 맞게 어떻게 커스터마이징해야 하는지를 아는 것입니다. 나쁜 선택은 시각화의 정확도를 조용히 망가뜨릴 수 있고, 좋은 선택은 복잡한 데이터도 즉시 읽히게 만듭니다.

이 가이드는 Matplotlib 컬러맵의 실무적인 모든 측면을 다룹니다. 네 가지 주요 카테고리, 가장 중요한 내장 컬러맵, 다양한 플롯 타입에 적용하는 방법, 커스텀 컬러맵을 처음부터 만드는 방법, 그리고 과학적으로 정확하면서도 접근성까지 고려한 컬러맵 선택 기준을 설명합니다.

📚

Matplotlib에서 Colormap이란?

컬러맵(colormap)은 스칼라(scalar) 데이터 값을 색으로 변환해 주는 매핑 함수입니다. 숫자 하나(대개 0--1 범위로 정규화됨)를 입력하면, 컬러맵이 RGBA 색상 튜플을 반환합니다. Matplotlib은 컬러맵을 matplotlib.colors.Colormap를 상속한 객체로 표현하며, cmap 파라미터를 받는 모든 플로팅 함수는 내부적으로 이 시스템을 사용합니다.

import matplotlib.pyplot as plt
import numpy as np
 
# A colormap is a callable: pass a float in [0, 1], get an RGBA tuple
cmap = plt.colormaps['viridis']
print(cmap(0.0))   # dark purple
print(cmap(0.5))   # teal-green
print(cmap(1.0))   # bright yellow

plt.imshow(data, cmap='viridis')처럼 작성하면 Matplotlib은 먼저 Normalize 객체를 이용해 데이터를 [0, 1]로 정규화한 뒤, 각 정규화 값을 컬러맵에 통과시켜 최종 픽셀 색을 만듭니다. 이 **두 단계 과정(정규화 → 색 조회)**을 이해하는 것이 플롯의 색을 원하는 대로 제어하는 핵심입니다.

Colormap의 네 가지 카테고리

Matplotlib은 컬러맵을 기능적으로 네 가지 카테고리로 정리합니다. 각 카테고리는 서로 다른 데이터 유형에 맞춰 설계되었으며, 잘못된 카테고리를 고르는 것이 가장 흔한 컬러맵 실수입니다.

Sequential Colormaps(순차형 컬러맵)

순차형 컬러맵은 하나의 색조 또는 좁은 색상 범위에서 밝음→어두움(또는 그 반대)으로 부드럽게 변합니다. 특별한 중간값 없이 낮음에서 높음으로 자연스러운 순서가 있는 데이터에 적합합니다.

사용 시점: 온도 측정값, 인구 밀도, 고도, 확률 등 “낮음→높음” 방향성이 의미 있는 연속 변수.

대표 예시: viridis, plasma, inferno, magma, cividis, Blues, Greens, OrRd, YlGnBu

import matplotlib.pyplot as plt
import numpy as np
 
data = np.random.rand(12, 12)
 
fig, axes = plt.subplots(1, 3, figsize=(14, 4))
 
for ax, name in zip(axes, ['viridis', 'plasma', 'inferno']):
    im = ax.imshow(data, cmap=name)
    ax.set_title(f'Sequential: {name}')
    fig.colorbar(im, ax=ax, shrink=0.8)
 
plt.tight_layout()
plt.show()

Diverging Colormaps(발산형 컬러맵)

발산형 컬러맵은 서로 대비되는 두 가지 색조가 중립적인 중간값(보통 흰색 또는 연한 회색)에서 만나도록 구성됩니다. 중심값을 기준으로 양쪽 방향의 편차를 강조합니다.

사용 시점: 온도 이상치(평균 대비 높음/낮음), 상관행렬, 손익(profit/loss), 0 또는 특정 기준점이 특별한 의미를 갖는 데이터.

대표 예시: coolwarm, RdBu, RdYlGn, BrBG, PiYG, seismic, bwr

import matplotlib.pyplot as plt
import numpy as np
 
np.random.seed(42)
data = np.random.randn(10, 10)  # Values centered around zero
 
fig, axes = plt.subplots(1, 3, figsize=(14, 4))
 
for ax, name in zip(axes, ['coolwarm', 'RdBu', 'seismic']):
    im = ax.imshow(data, cmap=name, vmin=-3, vmax=3)
    ax.set_title(f'Diverging: {name}')
    fig.colorbar(im, ax=ax, shrink=0.8)
 
plt.tight_layout()
plt.show()

Tip: 중립색이 0(또는 선택한 중심값)에 정확히 맞도록 vmin, vmax를 중심 기준으로 대칭이 되게 설정하세요.

Qualitative Colormaps(정성/범주형 컬러맵)

정성(qualitative) 컬러맵은 순서 의미 없이 서로 확연히 구분되는 색 집합을 제공합니다. 인접한 색끼리 최대한 다르게 보이도록 설계되어 범주 레이블에 적합합니다.

사용 시점: 클러스터 레이블, 범주형 산점도, 순서 없는 그룹의 막대 차트.

대표 예시: tab10, tab20, Set1, Set2, Set3, Paired, Accent

import matplotlib.pyplot as plt
import numpy as np
 
np.random.seed(7)
categories = 6
x = np.concatenate([np.random.randn(30) + i * 3 for i in range(categories)])
y = np.concatenate([np.random.randn(30) + i * 1.5 for i in range(categories)])
labels = np.concatenate([np.full(30, i) for i in range(categories)])
 
plt.figure(figsize=(9, 6))
scatter = plt.scatter(x, y, c=labels, cmap='tab10', s=50, alpha=0.8, edgecolors='white')
plt.colorbar(scatter, label='Category')
plt.title('Qualitative Colormap: tab10')
plt.xlabel('X')
plt.ylabel('Y')
plt.show()

Cyclic Colormaps(순환형 컬러맵)

순환형(cyclic) 컬러맵은 시작과 끝이 같은 색으로 이어져, 값이 “랩 어라운드(wrap around)”되는 데이터를 표현하기에 적합합니다. 예: 각도, 위상, 하루 시간, 풍향 등.

사용 시점: 위상 데이터, 나침반 방향, 주기 신호, 하루 24시간.

대표 예시: twilight, twilight_shifted, hsv

import matplotlib.pyplot as plt
import numpy as np
 
theta = np.linspace(0, 2 * np.pi, 300)
r = np.linspace(0, 1, 300)
T, R = np.meshgrid(theta, r)
Z = T  # Color represents angle
 
fig, ax = plt.subplots(subplot_kw={'projection': 'polar'}, figsize=(6, 6))
im = ax.pcolormesh(T, R, Z, cmap='twilight', shading='auto')
fig.colorbar(im, ax=ax, label='Angle (radians)')
ax.set_title('Cyclic Colormap: twilight')
plt.show()

비교 표: Colormap 카테고리

CategoryPurposeMidpoint Matters?Ordering?Best ForExamples
Sequential낮음→높음 값NoYes밀도, 온도, 카운트viridis, plasma, inferno, Blues
Diverging중심값으로부터의 편차YesYes (both directions)이상치, 상관, 손익coolwarm, RdBu, BrBG
Qualitative구분되는 범주NoNo레이블, 클러스터, 그룹tab10, Set1, Paired
Cyclic순환/랩핑 데이터NoCircular위상, 각도, 하루 시간twilight, hsv

내장 Colormap 레퍼런스

Matplotlib에는 여러 계열의 컬러맵이 포함되어 있습니다. 아래는 카테고리별로 가장 많이 쓰이는 컬러맵입니다.

Perceptually Uniform Sequential(지각적으로 균일한 순차형)

이 컬러맵들은 데이터에서 같은 간격(step)이 사람이 느끼는 밝기 변화에서도 같은 간격이 되도록 설계되었습니다. 대부분의 상황에서 기본 추천입니다.

ColormapDescriptionColorblind Safe
viridis보라→노랑, Matplotlib 2.0 이후 기본값Yes
plasma보라→노랑, 대비가 더 큼Yes
inferno검정→노랑(빨강 경유)Yes
magma검정→흰색(보라/핑크 경유)Yes
cividis파랑→노랑, 색각 이상 최적화Yes

많이 쓰는 Diverging Colormaps(발산형 컬러맵)

ColormapDescriptionColorblind Safe
coolwarm파랑→빨강, 부드러운 전이Partially
RdBu빨강→파랑, 강한 대비No
RdYlGn빨강-노랑-초록No
BrBG갈색→청록Partially
PiYG핑크→초록Partially
seismic파랑→빨강, 채도 강함No

플롯 타입별 Colormap 사용법

imshow로 히트맵 그리기

import matplotlib.pyplot as plt
import numpy as np
 
np.random.seed(42)
data = np.random.rand(8, 10)
 
fig, ax = plt.subplots(figsize=(10, 6))
im = ax.imshow(data, cmap='YlOrRd', aspect='auto')
ax.set_xlabel('Columns')
ax.set_ylabel('Rows')
ax.set_title('Heatmap with YlOrRd Colormap')
fig.colorbar(im, ax=ax, label='Value')
plt.tight_layout()
plt.show()

색으로 값을 인코딩하는 산점도

import matplotlib.pyplot as plt
import numpy as np
 
np.random.seed(42)
n = 300
x = np.random.randn(n)
y = np.random.randn(n)
distance = np.sqrt(x**2 + y**2)
 
plt.figure(figsize=(8, 6))
sc = plt.scatter(x, y, c=distance, cmap='magma', s=40, alpha=0.8, edgecolors='gray', linewidths=0.3)
plt.colorbar(sc, label='Distance from Origin')
plt.xlabel('X')
plt.ylabel('Y')
plt.title('Scatter Plot with magma Colormap')
plt.show()

컨투어(등고선) 플롯

import matplotlib.pyplot as plt
import numpy as np
 
x = np.linspace(-3, 3, 200)
y = np.linspace(-3, 3, 200)
X, Y = np.meshgrid(x, y)
Z = np.sin(X) * np.cos(Y)
 
fig, axes = plt.subplots(1, 2, figsize=(13, 5))
 
# Filled contour
cf = axes[0].contourf(X, Y, Z, levels=20, cmap='RdBu')
fig.colorbar(cf, ax=axes[0])
axes[0].set_title('contourf with RdBu')
 
# Line contour with colormap
cl = axes[1].contour(X, Y, Z, levels=15, cmap='plasma')
axes[1].clabel(cl, inline=True, fontsize=8)
axes[1].set_title('contour with plasma')
 
plt.tight_layout()
plt.show()

불규칙 그리드에 pcolormesh 사용하기

import matplotlib.pyplot as plt
import numpy as np
 
np.random.seed(0)
x = np.linspace(0, 4, 50)
y = np.linspace(0, 3, 40)
X, Y = np.meshgrid(x, y)
Z = np.exp(-(X - 2)**2 - (Y - 1.5)**2) + 0.5 * np.sin(3 * X) * np.cos(3 * Y)
 
plt.figure(figsize=(9, 6))
pcm = plt.pcolormesh(X, Y, Z, cmap='cividis', shading='auto')
plt.colorbar(pcm, label='Intensity')
plt.xlabel('X')
plt.ylabel('Y')
plt.title('pcolormesh with cividis Colormap')
plt.tight_layout()
plt.show()

Colorbar 커스터마이징

컬러바(colorbar)는 컬러맵의 범례(legend)입니다. 제대로 커스터마이징하는 것이 읽기 쉬운 시각화에 필수입니다.

기본 Colorbar 옵션

import matplotlib.pyplot as plt
import numpy as np
 
data = np.random.rand(10, 10)
 
fig, ax = plt.subplots(figsize=(8, 6))
im = ax.imshow(data, cmap='viridis')
 
cbar = fig.colorbar(im, ax=ax, orientation='vertical', shrink=0.8, pad=0.02)
cbar.set_label('Measurement Value', fontsize=12)
cbar.ax.tick_params(labelsize=10)
plt.title('Colorbar Customization')
plt.tight_layout()
plt.show()

BoundaryNorm로 이산형 Colorbar 만들기

데이터가 자연스럽게 이산 구간(리스크 레벨, 등급 카테고리)으로 나뉜다면, 부드러운 그라데이션 대신 BoundaryNorm으로 경계가 뚜렷한 색 구간을 만들 수 있습니다.

import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import numpy as np
 
data = np.random.rand(10, 10) * 100
 
bounds = [0, 20, 40, 60, 80, 100]
norm = mcolors.BoundaryNorm(bounds, ncolors=256)
 
fig, ax = plt.subplots(figsize=(8, 6))
im = ax.imshow(data, cmap='RdYlGn', norm=norm)
cbar = fig.colorbar(im, ax=ax, ticks=bounds)
cbar.set_label('Score')
ax.set_title('Discrete Colorbar with BoundaryNorm')
plt.tight_layout()
plt.show()

가로형 Colorbar

import matplotlib.pyplot as plt
import numpy as np
 
data = np.random.rand(8, 12)
 
fig, ax = plt.subplots(figsize=(10, 5))
im = ax.imshow(data, cmap='plasma')
cbar = fig.colorbar(im, ax=ax, orientation='horizontal', fraction=0.046, pad=0.12)
cbar.set_label('Value')
ax.set_title('Horizontal Colorbar')
plt.tight_layout()
plt.show()

커스텀 Colormap 만들기

내장 컬러맵이 요구사항에 맞지 않는 경우(기업 브랜드 컬러, 도메인 관례, 특정 지각 요구 등) Matplotlib은 직접 컬러맵을 만들 수 있는 두 가지 클래스를 제공합니다.

ListedColormap: 색 리스트로 만들기

ListedColormap은 명시적인 색 목록으로 컬러맵을 생성합니다. 각 색은 [0, 1] 구간에서 동일한 비율을 차지합니다.

import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import numpy as np
 
# Define colors by name, hex, or RGB tuple
colors = ['#2c3e50', '#2980b9', '#27ae60', '#f39c12', '#e74c3c']
cmap_custom = mcolors.ListedColormap(colors)
 
data = np.random.rand(10, 10)
 
fig, ax = plt.subplots(figsize=(8, 6))
im = ax.imshow(data, cmap=cmap_custom)
fig.colorbar(im, ax=ax)
ax.set_title('Custom ListedColormap (5 colors)')
plt.tight_layout()
plt.show()

LinearSegmentedColormap: 부드러운 그라데이션

LinearSegmentedColormap은 색이 부드럽게 전이되도록 만듭니다. 가장 간단한 방법은 from_list를 사용해 앵커 색(anchor colors) 사이를 선형 보간(interpolate)하는 것입니다.

import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import numpy as np
 
# Smooth gradient from dark blue through white to dark red
colors = ['#1a1a6e', '#4a90d9', '#ffffff', '#d94a4a', '#6e1a1a']
cmap_diverge = mcolors.LinearSegmentedColormap.from_list('custom_diverge', colors)
 
np.random.seed(42)
data = np.random.randn(12, 12)
 
fig, ax = plt.subplots(figsize=(8, 6))
im = ax.imshow(data, cmap=cmap_diverge, vmin=-3, vmax=3)
fig.colorbar(im, ax=ax, label='Standard Deviations')
ax.set_title('Custom Diverging Colormap')
plt.tight_layout()
plt.show()

고급: Segment Dictionary 포맷

각 색 채널이 어떻게 전이될지까지 완전히 제어하려면 segment dictionary를 정의합니다. 각 채널(red, green, blue)은 (x, y_left, y_right) 튜플 리스트를 가지며, 이는 앵커 포인트를 의미합니다.

import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import numpy as np
 
# Custom colormap: black -> blue -> cyan -> yellow -> white
cdict = {
    'red':   [(0.0, 0.0, 0.0), (0.25, 0.0, 0.0), (0.5, 0.0, 0.0),
              (0.75, 1.0, 1.0), (1.0, 1.0, 1.0)],
    'green': [(0.0, 0.0, 0.0), (0.25, 0.0, 0.0), (0.5, 1.0, 1.0),
              (0.75, 1.0, 1.0), (1.0, 1.0, 1.0)],
    'blue':  [(0.0, 0.0, 0.0), (0.25, 1.0, 1.0), (0.5, 1.0, 1.0),
              (0.75, 0.0, 0.0), (1.0, 1.0, 1.0)]
}
cmap_seg = mcolors.LinearSegmentedColormap('custom_seg', cdict)
 
data = np.random.rand(10, 10)
fig, ax = plt.subplots(figsize=(8, 6))
im = ax.imshow(data, cmap=cmap_seg)
fig.colorbar(im, ax=ax)
ax.set_title('Segment Dictionary Colormap')
plt.tight_layout()
plt.show()

커스텀 Colormap 등록하기

내장 컬러맵처럼 이름으로 참조할 수 있도록 컬러맵을 등록(register)할 수 있습니다.

import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
 
colors = ['#0d0887', '#7e03a8', '#cc4778', '#f89540', '#f0f921']
my_cmap = mcolors.LinearSegmentedColormap.from_list('my_palette', colors)
plt.colormaps.register(cmap=my_cmap)
 
# Now use it by name anywhere
# plt.imshow(data, cmap='my_palette')

Colormap 뒤집기(Reversing)

어떤 컬러맵 이름이든 뒤에 _r를 붙이면 반전 버전을 사용할 수 있습니다. 예를 들어, 높은 값을 밝게 보이게 하던 것을 어둡게 보이게 바꾸는 등 강조를 뒤집고 싶을 때 유용합니다.

import matplotlib.pyplot as plt
import numpy as np
 
data = np.random.rand(8, 8)
 
fig, axes = plt.subplots(1, 2, figsize=(12, 5))
 
axes[0].imshow(data, cmap='viridis')
axes[0].set_title('viridis (default)')
 
axes[1].imshow(data, cmap='viridis_r')
axes[1].set_title('viridis_r (reversed)')
 
plt.tight_layout()
plt.show()

모든 내장 컬러맵에는 반전 버전이 있습니다: plasma_r, coolwarm_r, RdBu_r, inferno_r 등.

Colormap 일부만 잘라 쓰기(Truncating) 및 부분집합 추출

컬러맵의 일부 구간만 필요할 때가 있습니다. Colormap.__call__np.linspace, 그리고 ListedColormap을 이용해 슬라이스를 추출할 수 있습니다.

import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import numpy as np
 
# Extract the middle 50% of the viridis colormap
full_cmap = plt.colormaps['viridis']
colors = full_cmap(np.linspace(0.25, 0.75, 256))
truncated_cmap = mcolors.ListedColormap(colors)
 
data = np.random.rand(10, 10)
 
fig, axes = plt.subplots(1, 2, figsize=(12, 5))
axes[0].imshow(data, cmap='viridis')
axes[0].set_title('Full viridis')
axes[1].imshow(data, cmap=truncated_cmap)
axes[1].set_title('Truncated viridis (25%-75%)')
plt.tight_layout()
plt.show()

정규화(Normalization): 데이터가 색으로 매핑되는 방식 제어

정규화는 컬러맵 조회 전에 원본 데이터를 [0, 1] 범위로 변환하는 방법을 결정합니다. 기본은 선형(linear)이지만 Matplotlib은 여러 대안을 제공합니다.

NormalizationClassWhen to Use
LinearNormalize기본값, 고르게 분포된 데이터
LogarithmicLogNorm자릿수(orders of magnitude) 차이가 큰 데이터
Symmetric logSymLogNorm양/음이 모두 있고 log처럼 스케일링이 필요할 때
PowerPowerNorm사용자 정의 비선형 압축
Two-slopeTwoSlopeNorm비대칭 범위의 발산형 데이터
BoundaryBoundaryNorm이산 구간 경계
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import numpy as np
 
np.random.seed(42)
data = np.random.lognormal(mean=2, sigma=1.5, size=(20, 20))
 
fig, axes = plt.subplots(1, 3, figsize=(16, 5))
 
# Linear (default)
im0 = axes[0].imshow(data, cmap='magma')
fig.colorbar(im0, ax=axes[0])
axes[0].set_title('Linear Normalize')
 
# LogNorm
im1 = axes[1].imshow(data, cmap='magma', norm=mcolors.LogNorm())
fig.colorbar(im1, ax=axes[1])
axes[1].set_title('LogNorm')
 
# PowerNorm (gamma=0.5 = square root)
im2 = axes[2].imshow(data, cmap='magma', norm=mcolors.PowerNorm(gamma=0.5))
fig.colorbar(im2, ax=axes[2])
axes[2].set_title('PowerNorm (gamma=0.5)')
 
plt.tight_layout()
plt.show()

데이터에 맞는 Colormap 고르는 법

올바른 컬러맵 선택은 실제 결과에 영향을 미치는 디자인 결정입니다. 아래는 실용적인 의사결정 프레임워크입니다.

  1. 데이터가 순차형(낮음→높음)인가? 순차형 컬러맵을 사용하세요. 기본은 viridis가 좋습니다. 대비가 더 필요하면 plasma 또는 inferno를 시도하세요.

  2. 데이터가 의미 있는 중심값을 기준으로 발산하는가? 발산형 컬러맵을 사용하세요. 은은한 느낌은 coolwarm, 강한 대비는 RdBu. vmin, vmax를 대칭으로 설정하세요.

  3. 순서가 없는 범주형 데이터인가? 정성(qualitative) 컬러맵을 사용하세요. 최대 10개 범주는 tab10, 최대 20개는 tab20.

  4. 데이터가 랩핑(각도/위상)되는가? 순환형 컬러맵을 사용하세요. 최신 옵션으로는 twilight가 가장 좋습니다.

  5. 색각 이상 사용자가 포함될 수 있는가? cividis(순차형) 또는 viridis를 사용하세요. RdYlGn 같은 적-녹 조합은 피하세요.

  6. 그림이 흑백으로 인쇄될 수 있는가? viridis, plasma, inferno, magma를 사용하세요. 이들은 명도(lightness)가 단조 증가하여 흑백에서도 구분이 잘 됩니다.

접근성: 색각 이상 친화적인 Colormaps

남성의 약 8%, 여성의 약 0.5%는 어떤 형태로든 색각 이상을 가지고 있으며, 가장 흔한 유형은 적색과 녹색을 구분하기 어려운 경우입니다. 지각적으로 균일한 컬러맵(viridis, plasma, inferno, magma, cividis)은 가장 흔한 색각 이상 조건에서도 읽히도록 특별히 설계되었습니다.

접근성 측면에서 피해야 할 컬러맵: jet, rainbow, RdYlGn, RdYlBu(적-녹 구분이 중요한 경우), hot.

jet이 해로운 이유: jet 컬러맵(파랑→청록→초록→노랑→빨강 무지개)은 지각적 비균일성 때문에 데이터에 존재하지 않는 경계를 만들어 냅니다. 실제 값 차이가 큰 영역이 비슷하게 보일 수 있고, 청록-초록 부근의 작은 차이는 과장되어 보일 수 있습니다. 또한 deuteranopia(적-녹 색각 이상) 사용자에게는 사실상 제대로 동작하지 않습니다.

import matplotlib.pyplot as plt
import numpy as np
 
np.random.seed(42)
data = np.random.rand(15, 15)
 
fig, axes = plt.subplots(1, 2, figsize=(12, 5))
 
axes[0].imshow(data, cmap='jet')
axes[0].set_title('jet (avoid for scientific use)')
 
axes[1].imshow(data, cmap='cividis')
axes[1].set_title('cividis (colorblind-safe)')
 
plt.tight_layout()
plt.show()

사용 가능한 모든 Colormap 나열하기

사용 중인 Matplotlib 버전에서 사용할 수 있는 모든 컬러맵을 확인하려면:

import matplotlib.pyplot as plt
 
# All colormap names, sorted
all_cmaps = sorted(plt.colormaps())
print(f"Total colormaps: {len(all_cmaps)}")
 
# Filter out reversed versions
base_cmaps = [c for c in all_cmaps if not c.endswith('_r')]
print(f"Base colormaps (excluding _r): {len(base_cmaps)}")

시각적으로 표시하려면:

import matplotlib.pyplot as plt
import numpy as np
 
gradient = np.linspace(0, 1, 256).reshape(1, -1)
 
cmaps_to_show = ['viridis', 'plasma', 'inferno', 'magma', 'cividis',
                 'coolwarm', 'RdBu', 'seismic',
                 'tab10', 'Set1',
                 'twilight']
 
fig, axes = plt.subplots(len(cmaps_to_show), 1, figsize=(10, len(cmaps_to_show) * 0.5))
fig.subplots_adjust(hspace=0.4)
 
for ax, name in zip(axes, cmaps_to_show):
    ax.imshow(gradient, aspect='auto', cmap=name)
    ax.set_ylabel(name, rotation=0, labelpad=80, fontsize=10, va='center')
    ax.set_xticks([])
    ax.set_yticks([])
 
fig.suptitle('Matplotlib Colormap Samples', fontsize=14, y=1.01)
plt.tight_layout()
plt.show()

PyGWalker로 인터랙티브 시각화하기

데이터셋을 인터랙티브하게 탐색할 때는, 매 플롯마다 컬러맵을 손으로 구성하는 작업이 속도를 떨어뜨릴 수 있습니다. PyGWalker (opens in a new tab)는 pandas 또는 polars DataFrame을 Jupyter 안에서 바로 Tableau 스타일의 인터랙티브 인터페이스로 바꿔주는 오픈소스 Python 라이브러리입니다. 변수를 축에 드래그하고, 색 인코딩을 지정하고, 시각화 타입을 바꾸는 일을 컬러맵/플로팅 코드를 직접 작성하지 않고도 할 수 있습니다.

import pandas as pd
import pygwalker as pyg
 
# Load your data
df = pd.read_csv('your_data.csv')
 
# Launch the interactive UI -- color encoding, binning, and filtering are all point-and-click
walker = pyg.walk(df)

이는 아직 어떤 변수를 시각화할지, 어떤 색 인코딩이 패턴을 가장 명확하게 보여줄지 결정하는 중인 탐색적 분석 단계에서 특히 유용합니다. 적절한 시각화를 찾았다면, 이후에는 Matplotlib에서 정밀한 컬러맵 설정으로 그대로 재현하면 됩니다.

흔한 함정과 피하는 방법

PitfallProblemSolution
기본값처럼 jet 사용지각적 비균일성, 접근성 낮음viridis 또는 다른 지각적으로 균일한 맵으로 변경
순차형 데이터에 발산형 맵 사용존재하지 않는 중심값을 암시순차형 맵 사용
발산형 데이터에 순차형 맵 사용중심 기준 위/아래 구분이 약해짐대칭 vmin/vmax와 함께 발산형 맵 사용
발산형 맵에서 vmin/vmax 미설정중립색이 0에 맞지 않을 수 있음대칭 한계를 명시적으로 설정
많은 범주를 순차형 맵으로 표현비슷한 색이 구분되지 않음정성 맵(tab10, Set1) 사용
색각 이상 사용자 무시남성 시청자 약 8%가 읽기 어려움viridis, cividis 사용 또는 시뮬레이션으로 테스트

FAQ

Matplotlib에서 colormap이란 무엇인가요?

Matplotlib에서 colormap은 스칼라(수치) 값을 색으로 매핑하는 함수입니다. 0과 1 사이의 값을 받아 RGBA 색상 튜플을 반환합니다. imshow, scatter, contourf, pcolormesh 같은 함수에서 색 그라데이션으로 데이터를 시각화할 때 사용합니다. plt.colormaps['name']로 접근하거나 cmap 파라미터에 이름 문자열을 넘길 수 있습니다.

데이터에 맞는 colormap은 어떻게 고르나요?

순차형 데이터(낮음→높음)에는 viridis, plasma, inferno를 사용하세요. 발산형 데이터(중심값으로부터의 편차)에는 coolwarm 또는 RdBu가 좋습니다. 범주형 데이터에는 tab10 또는 Set1을 사용하세요. 각도 같은 순환형 데이터에는 twilight를 사용하세요. 또한 접근성을 항상 고려해야 하며, viridiscividis는 색각 이상 사용자에게도 안전합니다.

Matplotlib에서 커스텀 colormap은 어떻게 만들나요?

특정 색 목록으로 컬러맵을 만들려면 matplotlib.colors.ListedColormap을 사용하고, 앵커 색 사이의 부드러운 그라데이션을 만들려면 matplotlib.colors.LinearSegmentedColormap.from_list('name', colors)를 사용합니다. plt.colormaps.register()로 등록하면 이름으로 사용할 수 있습니다.

Matplotlib에서 colormap을 어떻게 반전하나요?

컬러맵 이름 뒤에 _r를 붙이면 됩니다. 예: cmap='viridis_r'는 viridis의 반전 버전입니다. 모든 내장 컬러맵에서 동작합니다. 커스텀 컬러맵은 colormap 객체에서 .reversed() 메서드를 호출하면 됩니다.

왜 jet colormap을 피해야 하나요?

jet 컬러맵은 지각적으로 균일하지 않아 가짜 경계를 만들고 실제 패턴을 숨길 수 있습니다. 또한 적-녹 색각 이상 사용자에게는 제대로 보이지 않습니다. Matplotlib이 2.0 버전에서 기본값을 jet에서 viridis로 바꾼 것도 이런 문제 때문입니다. 대신 viridis, plasma, cividis를 사용하세요.

Matplotlib 플롯에 colorbar는 어떻게 추가하나요?

imshow, scatter, contourf 등에서 반환되는 객체(mappable)를 plt.colorbar(mappable)에 넘기면 됩니다. label, orientation('horizontal' 또는 'vertical'), shrink, pad 같은 파라미터로 커스터마이징할 수 있습니다. 더 세밀한 제어는 cbar.ax로 colorbar의 axes에 접근해 설정합니다.

결론

컬러맵은 장식이 아니라 기능입니다. 시각화가 진실을 정확히 전달할지, 아니면 오해를 만들지까지 좌우합니다. Matplotlib은 네 가지 명확한 카테고리(순차형, 발산형, 정성/범주형, 순환형)로 정리된 풍부한 내장 컬러맵 라이브러리와, 필요하다면 완전히 커스텀 컬러맵을 만들 수 있는 도구를 제공합니다. 순차형 데이터라면 지각적으로 균일한 계열(viridis, plasma, inferno, magma, cividis)을 기본 출발점으로 삼는 것이 가장 안전합니다. 발산형 데이터라면 coolwarm 또는 RdBu 같은 맵을 고르고, 중립색이 의미 있는 중심값에 오도록 항상 기준을 맞추세요. 범주형 데이터에는 tab10 또는 Set1을 사용하세요. 그리고 무엇보다도, 시청자를 고려해야 합니다. 색각 이상 친화적인 컬러맵을 사용하는 것은 선택 사항이 아니라, 전문적인 실무 관행입니다.

📚