메모
전체 예제 코드를 다운로드 하려면 여기 를 클릭 하십시오.
Matplotlib에서 컬러맵 만들기 #
Matplotlib에는
matplotlib.colormaps
. 추가 컬러 맵이 많은 palettable 과 같은 외부 라이브러리도 있습니다
.
그러나 우리는 종종 Matplotlib에서 컬러맵을 생성하거나 조작하기를 원합니다. 이것은 클래스 ListedColormap
또는
를 사용하여 수행할 수 있습니다 LinearSegmentedColormap
. 외부에서 볼 때 두 컬러맵 클래스는 0과 1 사이의 값을 여러 색상에 매핑합니다. 그러나 약간의 차이가 있으며 그 중 일부는 다음과 같습니다.
컬러맵을 수동으로 생성하거나 조작하기 전에 먼저 기존 컬러맵 클래스에서 컬러맵과 해당 색상을 얻는 방법을 살펴보겠습니다.
색상표 가져오기 및 해당 값에 액세스 #
먼저 이름이 지정된 컬러맵을 가져오는데 대부분이 Matplotlib에서 컬러맵 선택 에 나열되어 있으며
컬러 matplotlib.colormaps
맵 객체를 반환하는 를 사용하여 수행할 수 있습니다 . 컬러맵을 정의하기 위해 내부적으로 사용되는 색상 목록의 길이는 를 통해 조정할 수 있습니다 Colormap.resampled
. 아래에서는 적당한 값인 8을 사용하므로 살펴볼 값이 많지 않습니다.
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
from matplotlib.colors import ListedColormap, LinearSegmentedColormap
viridis = mpl.colormaps['viridis'].resampled(8)
객체 viridis
는 콜러블이며 0과 1 사이의 부동 소수점을 전달하면 색상표에서 RGBA 값을 반환합니다.
print(viridis(0.56))
(0.122312, 0.633153, 0.530398, 1.0)
ListedColormap #
ListedColormap
s는 색상 값을 .colors
속성에 저장합니다. 컬러맵을 구성하는 색상 목록은 속성을 사용하여 직접 액세스하거나 컬러맵 의 길이와 일치하는 값 배열을 colors
호출하여 간접적으로 액세스할 수 있습니다 . viridis
반환된 목록은 RGBA Nx4 배열 형식이며 여기서 N은 컬러맵의 길이입니다.
print('viridis.colors', viridis.colors)
print('viridis(range(8))', viridis(range(8)))
print('viridis(np.linspace(0, 1, 8))', viridis(np.linspace(0, 1, 8)))
viridis.colors [[0.267004 0.004874 0.329415 1. ]
[0.275191 0.194905 0.496005 1. ]
[0.212395 0.359683 0.55171 1. ]
[0.153364 0.497 0.557724 1. ]
[0.122312 0.633153 0.530398 1. ]
[0.288921 0.758394 0.428426 1. ]
[0.626579 0.854645 0.223353 1. ]
[0.993248 0.906157 0.143936 1. ]]
viridis(range(8)) [[0.267004 0.004874 0.329415 1. ]
[0.275191 0.194905 0.496005 1. ]
[0.212395 0.359683 0.55171 1. ]
[0.153364 0.497 0.557724 1. ]
[0.122312 0.633153 0.530398 1. ]
[0.288921 0.758394 0.428426 1. ]
[0.626579 0.854645 0.223353 1. ]
[0.993248 0.906157 0.143936 1. ]]
viridis(np.linspace(0, 1, 8)) [[0.267004 0.004874 0.329415 1. ]
[0.275191 0.194905 0.496005 1. ]
[0.212395 0.359683 0.55171 1. ]
[0.153364 0.497 0.557724 1. ]
[0.122312 0.633153 0.530398 1. ]
[0.288921 0.758394 0.428426 1. ]
[0.626579 0.854645 0.223353 1. ]
[0.993248 0.906157 0.143936 1. ]]
컬러맵은 조회 테이블이므로 컬러맵을 "오버샘플링"하면 가장 가까운 이웃 보간법이 반환됩니다(아래 목록에서 반복되는 색상 참고).
print('viridis(np.linspace(0, 1, 12))', viridis(np.linspace(0, 1, 12)))
viridis(np.linspace(0, 1, 12)) [[0.267004 0.004874 0.329415 1. ]
[0.267004 0.004874 0.329415 1. ]
[0.275191 0.194905 0.496005 1. ]
[0.212395 0.359683 0.55171 1. ]
[0.212395 0.359683 0.55171 1. ]
[0.153364 0.497 0.557724 1. ]
[0.122312 0.633153 0.530398 1. ]
[0.288921 0.758394 0.428426 1. ]
[0.288921 0.758394 0.428426 1. ]
[0.626579 0.854645 0.223353 1. ]
[0.993248 0.906157 0.143936 1. ]
[0.993248 0.906157 0.143936 1. ]]
LinearSegmentedColormap #
LinearSegmentedColormap
s에는 .colors
속성이 없습니다. 그러나 여전히 정수 배열 또는 0과 1 사이의 부동 소수점 배열을 사용하여 컬러맵을 호출할 수 있습니다.
copper = mpl.colormaps['copper'].resampled(8)
print('copper(range(8))', copper(range(8)))
print('copper(np.linspace(0, 1, 8))', copper(np.linspace(0, 1, 8)))
copper(range(8)) [[0. 0. 0. 1. ]
[0.17647055 0.1116 0.07107143 1. ]
[0.35294109 0.2232 0.14214286 1. ]
[0.52941164 0.3348 0.21321429 1. ]
[0.70588219 0.4464 0.28428571 1. ]
[0.88235273 0.558 0.35535714 1. ]
[1. 0.6696 0.42642857 1. ]
[1. 0.7812 0.4975 1. ]]
copper(np.linspace(0, 1, 8)) [[0. 0. 0. 1. ]
[0.17647055 0.1116 0.07107143 1. ]
[0.35294109 0.2232 0.14214286 1. ]
[0.52941164 0.3348 0.21321429 1. ]
[0.70588219 0.4464 0.28428571 1. ]
[0.88235273 0.558 0.35535714 1. ]
[1. 0.6696 0.42642857 1. ]
[1. 0.7812 0.4975 1. ]]
나열된 컬러맵 만들기 #
컬러맵을 생성하는 것은 본질적으로 새로운 컬러맵을 생성하기 위해 색상 사양의 목록 또는 배열을 제공하는 위 작업의 반대 작업입니다 ListedColormap
.
자습서를 계속하기 전에 하나 이상의 컬러맵을 입력으로 사용하고 임의의 데이터를 생성한 다음 컬러맵을 해당 데이터 집합의 이미지 플롯에 적용하는 도우미 함수를 정의해 보겠습니다.
def plot_examples(colormaps):
"""
Helper function to plot data with associated colormap.
"""
np.random.seed(19680801)
data = np.random.randn(30, 30)
n = len(colormaps)
fig, axs = plt.subplots(1, n, figsize=(n * 2 + 2, 3),
constrained_layout=True, squeeze=False)
for [ax, cmap] in zip(axs.flat, colormaps):
psm = ax.pcolormesh(data, cmap=cmap, rasterized=True, vmin=-4, vmax=4)
fig.colorbar(psm, ax=ax)
plt.show()
가장 간단한 경우에는 색상 이름 목록을 입력하여 색상표를 만들 수 있습니다.
cmap = ListedColormap(["darkorange", "gold", "lawngreen", "lightseagreen"])
plot_examples([cmap])
실제로 이 목록에는 유효한 Matplotlib 색상 사양 이 포함될 수 있습니다 . 사용자 정의 컬러맵을 생성하는 데 특히 유용한 것은 Nx4 numpy 배열입니다. 이러한 배열에서 수행할 수 있는 다양한 numpy 작업을 통해 기존 컬러맵에서 새 컬러맵을 만드는 작업이 매우 간단해집니다.
예를 들어 어떤 이유로 256 길이의 "viridis" 컬러맵의 처음 25개 항목을 분홍색으로 만들고 싶다고 가정합니다.
viridis = mpl.colormaps['viridis'].resampled(256)
newcolors = viridis(np.linspace(0, 1, 256))
pink = np.array([248/256, 24/256, 148/256, 1])
newcolors[:25, :] = pink
newcmp = ListedColormap(newcolors)
plot_examples([viridis, newcmp])
컬러맵의 동적 범위를 줄일 수 있습니다. 여기서 우리는 컬러맵의 중간 절반을 선택합니다. 그러나 viridis는 나열된 컬러맵이기 때문에 원래 컬러맵에 있던 256개의 값 대신 128개의 불연속 값으로 끝납니다. 이 방법은 새 색상을 추가하기 위해 색상 공간에서 보간하지 않습니다.
viridis_big = mpl.colormaps['viridis']
newcmp = ListedColormap(viridis_big(np.linspace(0.25, 0.75, 128)))
plot_examples([viridis, newcmp])
두 개의 컬러맵을 쉽게 연결할 수 있습니다.
top = mpl.colormaps['Oranges_r'].resampled(128)
bottom = mpl.colormaps['Blues'].resampled(128)
newcolors = np.vstack((top(np.linspace(0, 1, 128)),
bottom(np.linspace(0, 1, 128))))
newcmp = ListedColormap(newcolors, name='OrangeBlue')
plot_examples([viridis, newcmp])
물론 명명된 컬러맵에서 시작할 필요는 없으며 에 전달할 Nx4 배열을 생성하기만 하면 됩니다 ListedColormap
. 여기에서는 갈색(RGB: 90, 40, 40)에서 흰색(RGB: 255, 255, 255)으로 가는 컬러맵을 만듭니다.
N = 256
vals = np.ones((N, 4))
vals[:, 0] = np.linspace(90/256, 1, N)
vals[:, 1] = np.linspace(40/256, 1, N)
vals[:, 2] = np.linspace(40/256, 1, N)
newcmp = ListedColormap(vals)
plot_examples([viridis, newcmp])
선형 세그먼트 컬러맵 만들기 #
이 LinearSegmentedColormap
클래스는 RGB(A) 값이 보간되는 앵커 포인트를 사용하여 컬러맵을 지정합니다.
이러한 컬러맵을 지정하는 형식은 앵커 포인트에서 불연속성을 허용합니다. 각 앵커 포인트는 형식의 행렬에서 행으로 지정됩니다. 여기서 는 앵커이고
는 앵커 포인트 양쪽의 색상 값입니다.[x[i] yleft[i] yright[i]]
x[i]
yleft[i]
yright[i]
불연속성이 없으면 다음 과 같습니다.yleft[i] == yright[i]
cdict = {'red': [[0.0, 0.0, 0.0],
[0.5, 1.0, 1.0],
[1.0, 1.0, 1.0]],
'green': [[0.0, 0.0, 0.0],
[0.25, 0.0, 0.0],
[0.75, 1.0, 1.0],
[1.0, 1.0, 1.0]],
'blue': [[0.0, 0.0, 0.0],
[0.5, 0.0, 0.0],
[1.0, 1.0, 1.0]]}
def plot_linearmap(cdict):
newcmp = LinearSegmentedColormap('testCmap', segmentdata=cdict, N=256)
rgba = newcmp(np.linspace(0, 1, 256))
fig, ax = plt.subplots(figsize=(4, 3), constrained_layout=True)
col = ['r', 'g', 'b']
for xx in [0.25, 0.5, 0.75]:
ax.axvline(xx, color='0.7', linestyle='--')
for i in range(3):
ax.plot(np.arange(256)/256, rgba[:, i], color=col[i])
ax.set_xlabel('index')
ax.set_ylabel('RGB')
plt.show()
plot_linearmap(cdict)
앵커 포인트에서 불연속성을 만들기 위해 세 번째 열은 두 번째 열과 다릅니다. 각각의 "빨간색", "녹색", "파란색" 및 선택적으로 "알파"에 대한 행렬은 다음과 같이 설정됩니다.
cdict['red'] = [...
[x[i] yleft[i] yright[i]],
[x[i+1] yleft[i+1] yright[i+1]],
...]
x[i]
및 사이의 컬러맵에 전달된 값 x[i+1]
의 경우 보간은 yright[i]
및 사이 yleft[i+1]
입니다.
아래 예에서는 0.5에서 빨간색 불연속성이 있습니다. 0과 0.5 사이의 보간은 0.3에서 1로 이동하고 0.5와 1 사이에서는 0.9에서 1로 이동합니다. ( 즉 , )가 0의 왼쪽에 있는 값이고 ( 즉, )는 색상 매핑 도메인 외부에 있는 1의 오른쪽에 있는 값입니다.red[0, 1]
red[2, 2]
red[0, 1]
yleft[0]
red[2, 2]
yright[2]
목록에서 분할된 컬러맵 직접 생성 #
위에서 설명한 접근 방식은 매우 다양하지만 구현하기 다소 번거롭습니다. 일부 기본적인 경우에는 사용이
LinearSegmentedColormap.from_list
더 쉬울 수 있습니다. 이렇게 하면 제공된 색상 목록에서 동일한 간격으로 분할된 색상표가 생성됩니다.
colors = ["darkorange", "gold", "lawngreen", "lightseagreen"]
cmap1 = LinearSegmentedColormap.from_list("mycmap", colors)
원하는 경우 컬러맵의 노드를 0과 1 사이의 숫자로 지정할 수 있습니다. 예를 들어 빨간색 부분이 컬러맵에서 더 많은 공간을 차지하도록 할 수 있습니다.
참조
다음 함수, 메서드, 클래스 및 모듈의 사용이 이 예제에 표시됩니다.
스크립트의 총 실행 시간: (0분 4.802초)