Matplotlib 색 맵: 컬러 스키ーム을 사용자 정의

데이터 시각화는 데이터 분석가와 데이터 과학자가 복잡한 정보를 표현하고 의미 있는 통찰을 얻는 가장 좋은 방법 중 하나(또는 최고의 방법)입니다. 이해관계자와 소통할 기회를 최대한 활용하기 위해, Matplotlib 색상 맵에 대한 유용한 정보를 모아뒀습니다.

이 글에서 보게 될 것처럼, Matplotlib은 Python에서 매우 다재다능하고 확장 가능한 시각화 라이브러리입니다. 단순한 차트에서 완전히 상호작용 가능한 시각화까지 모든 옵션을 제공합니다. Python에 익숙하지 않다면, 시작하기 전에 Python入门 과정에 등록해 기초를 이해할 것을 권장합니다. 개인적으로 저는 Python 찾아보기를 항상 가까이 두고 있어, 일반 함수에 대한 유용한 참고 자료로 사용합니다.

적절한 Matplotlib 색상 맵 선택

가장 먼저 고려해야 할 사항 중 하나는 순차적, 분岐적, 또는 범주적 컬러맵 중 선택하는 것입니다. 컬러맵을 선택할 때 고려해야 할 다른 중요한 요소로는 인식적 균일성, 즉 데이터 값의 동일한 차이가 색상의 동일한 차이로 인식되는 것과 색약 친화적 컬러맵 옵션을 사용하여 모든 청중에게 시각 자료를 접근 가능하게 하는 것입니다.

컬러맵을 선택할 때 다른 도메인 표준도 고려해야 합니다. 예를 들어, 해양학 연구에서는 파란색의 다른 톤이 물의 다른 깊이를 나타냅니다. 시각화에 적절한 컬러맵을 모르겠다면, 다양한 도구와 자원을 활용할 수 있습니다. 특히, 우리의 Introduction to Data Visualization with Matplotlib 과정은 많은 시나리오를 통해 도와줍니다.

Matplotlib의 다양한 컬러맵

Python에서는 matplotlib.colormaps 모듈을 통해 내장된 컬러맵에 접근할 수 있어 프로젝트에 가장 적합한 방법을 선택하는 데 도움이 됩니다. 다음은 가장 일반적인 카테고리의 옵션들입니다:

순차적 컬러맵

순차적 컬러맵은 낮은 값에서 높은 값으로 진행되는 순차적인 데이터를 나타냅니다. 이들은 밝은 색에서 어두운 색으로의 전이를 통해 다양한 수준에서 데이터의 크기를 보여줍니다. 순차적 컬러맵의 예로는 온도 데이터의 히트맵에서 사용되는 것이 있으며, 더 밝은 색은 더 차가운 온도를 나타내고, 더 어두운 색은 더 뜨거운 온도를 나타냅니다.

날짜와 온도 열이 있는 데이터셋이 있다고 가정해 봅시다. 다음 코드는 온도에 대한 히트맵을 생성합니다.

필요한 라이브러리 임포트 import numpy as np import pandas as pd import matplotlib.pyplot as plt import matplotlib.colors as mcolors 단계 1: 날짜 열에서 월과 일 정보 추출 calendar_data = temperature_data.copy() 작업을 위한 복사본 생성 calendar_data['Month'] = calendar_data['Date'].dt.strftime('%B') calendar_data['Day'] = calendar_data['Date'].dt.day 단계 2: 자연 캘린더 순서를 정의 month_names = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'] '월' 열을 지정된 순서로 범주형 타입으로 변환 calendar_data['Month'] = pd.Categorical(calendar_data['Month'], categories=month_names, ordered=True) 단계 3: 히트맵을 위한 데이터 피벗 monthly_temperature_table = calendar_data.pivot(index='Month', columns='Day', values='Temperature') 단계 4: 히트맵 그래프 설정 plt.figure(figsize=(12, 8)) 옵션: 온도 범위에 대한 커스텀 정규화 정의 norm = mcolors.Normalize(vmin=15, vmax=35) 순차 컬러맵으로 히트맵 생성 heatmap = plt.imshow(monthly_temperature_table, cmap='YlOrRd', aspect='auto', norm=norm) 온도를 나타내는 컬러 바 추가 colorbar = plt.colorbar(heatmap, orientation='horizontal') colorbar.set_label('Temperature (°C)', labelpad=10) 축 레이블 지정 plt.xlabel('Day of the Month') plt.ylabel('Month') y 축 틱을 숫자 대신 월 이름으로 표시 plt.yticks(ticks=np.arange(len(month_names)), labels=month_names) 히트맵에 제목 추가 plt.title('Monthly Temperature Heatmap (Sequential Colormap)') 그래프 표시 plt.grid(False) plt.show()

Matplotlib 순차 컬러맵 시각화 예제. 저자 이미지

이분 컬러맵

차이를 중앙 값에서 양방향으로 나타내는 데이터를 강조하는 데 사용되는 컬러맵을 이탈하는 컬러맵입니다. 이탈하는 컬러맵은 양성 방향과 음성 방향에 대비되는 색상을 가집니다. 이탈하는 컬러맵의 일반적인 용도는 재정 데이터에서 이익과 손실을 나타내는 것입니다.

# 'Month'을 인덱스로 설정 profit_loss_df.set_index('Month', inplace=True) # 그림 크기를 설정 plt.figure(figsize=(8, 4)) # 이탈하는 컬러맵 생성 cmap = plt.cm.RdYlGn # imshow를 사용하여 데이터를 히트맵으로 표시 im = plt.imshow(profit_loss_df.T, cmap=cmap, aspect='auto', vmin=-np.max(np.abs(profit_loss_data)), vmax=np.max(np.abs(profit_loss_data))) # 레이블이 있는 컬러 바 추가 cbar = plt.colorbar(im) cbar.set_label('Profit/Loss ($)') # 각 셀에 주석 추가 for i, month in enumerate(profit_loss_df.index): plt.text(i, 0, f'{profit_loss_df.loc[month, "Profit/Loss"]:.2f}', ha='center', va='center', color='black') # x축과 y축 레이블 및 틱 설정 plt.xlabel('Month') plt.ylabel('') # y축에 레이블이 필요하지 않음 plt.xticks(ticks=range(len(profit_loss_df.index)), labels=profit_loss_df.index, rotation=45) plt.yticks([]) # 단일 행만 있는 경우 y축 틱 숨김 # 제목 추가 plt.title('Profit/Loss Heatmap (Diverging Colormap)') # 더 나은 표시를 위한 레이아웃 조정 plt.tight_layout() # 그래프 표시 plt.show()

Matplotlib 이탈하는 컬러맵 시각화 예제. 저자 이미지.

순환 컬러맵

순환 컬러맵은 각도, 파동 위상, 하루 시간과 같은 반복되거나 주기적인 패턴을 나타내는 데이터를 시각화하는 데 유용합니다. 주기 함수의 단계를 시각화하는 것처럼 순환 컬러맵이 작동하는 예시는 주파수의的正弦파입니다.

# 사인파에 대한 데이터 생성 x = np.linspace(0, 2 * np.pi, 100) # 0에서 2π까지의 X 값 (완전한 주기) y = np.sin(x) # Y 값 (X의 사인) # 그림과 축 생성 plt.figure(figsize=(10, 6)) # 순환 컬러맵을 사용한 산점 그래프 생성 # 사인파 주기 내에서의 위치에 따라 점을 컬러링 points = plt.scatter(x, y, c=x, cmap='twilight', edgecolor='black') # 파의 위상을 보여주는 컬러 바 추가 cbar = plt.colorbar(points) cbar.set_label('Wave Phase (Radians)', rotation=270, labelpad=15) # 축을 레이블링 plt.xlabel('Angle (Radians)') plt.ylabel('Sine Value') # 제목 추가 plt.title('Sine Wave with Cyclic Colormap (Twilight)') # 그래프 표시 plt.grid(True) plt.show()

Matplotlib 순환 컬러맵 시각화 예제. 저자 이미지.

질적 컬러맵

질적인 색맵은 카테고리의 특정 순서가 없는 카테고리 데이터를 표현하는 데 이상적입니다. 질적인 색맵의 일반적인 사용 사례는 각 세그먼트가 다른 카테고리를 나타내는 파이 차트로, 각 카테고리를 쉽게 구분할 수 있습니다.

# 샘플 카테고리 데이터 categories = ['Category A', 'Category B', 'Category C', 'Category D', 'Category E'] values = [20, 35, 25, 10, 10] # 그림 크기 설정 plt.figure(figsize=(8, 8)) # 수동으로 정의한 질적인 색맵 colors = ['#8dd3c7', '#ffffb3', '#bebada', '#fb8072', '#80b1d3'] # 수동으로 선택한 색상十六진 코드 # 파이 차트 생성 plt.pie(values, labels=categories, autopct='%1.1f%%', startangle=90, colors=colors) # 동일한 비율로 파이가 원형으로 그려지도록 설정 plt.axis('equal') # 제목 추가 plt.title('Pie Chart with Qualitative Colormap') # 차트 표시 plt.show()

Matplotlib 질적 색맵 시각화 예제. 저자 이미지.

무지개 색맵

무지개 색맵은 hsv와 같이 넓은 범위의 색상이 필요할 때 사용됩니다.

순환 데이터 생성 x = np.linspace(0, 2 * np.pi, 500) y = np.sin(x) 무지개 컬러맵으로 그래프 그리기 plt.scatter(x, y, c=x, cmap='hsv', s=50) 컬러 바 추가 plt.colorbar(label='Phase') 레이블과 제목 추가 plt.xlabel('Angle (radians)') plt.ylabel('Sine Value') plt.title('Cyclic Data Visualization using HSV Colormap') 그래프 표시 plt.show()

Matplotlib 무지개 컬러맵 시각화 예제. 저자 이미지.

시각적으로 일관된 컬러맵

infernoplasma와 같은 컬러맵은 다양한 디스플레이 매체에서 더 나은 가시성을 제공합니다.

합성 고도 데이터 생성 x = np.linspace(-5, 5, 100) y = np.linspace(-5, 5, 100) X, Y = np.meshgrid(x, y) Z = np.sin(np.sqrt(X**2 + Y**2)) * 100 고도 데이터 'plasma' 컬러맵을 사용하여 고도 데이터 그래프 그리기 plt.contourf(X, Y, Z, cmap='plasma') 컬러 바 추가 plt.colorbar(label='Elevation (m)') 제목과 레이블 추가 plt.title('Topographic Map (Plasma Colormap)') plt.xlabel('X Coordinate') plt.ylabel('Y Coordinate') 그래프 표시 plt.show()

Matplotlib 감각적으로 일관된 컬러맵 시각화 예제. 저자 이미지.

Matplotlib 컬러맵 생성 및 수정

Matplotlib에는 다양한 내장 컬러맵이 있지만, 컬러를 맞춤형으로 설정하고 싶은 상황이 있을 수 있습니다. Matplotlib에서 맞춤형 컬러맵을 생성하는 데 사용되는 주요 도구는 ListedColormapLinearSegmentedColormap입니다.

ListedColormap으로 맞춤형 컬러맵 생성

ListedColormap은 특정 색상 목록에서 컬러맵을 생성할 수 있게 해줍니다. 이 방법은 범주 데이터에서 특정 범주에 특정 색상을 할당할 때 유용합니다.

from matplotlib.colors import ListedColormap 카테고리 데이터 categories = ['Category A', 'Category B', 'Category C', 'Category D'] values = [25, 40, 35, 30] 칼러맵에 사용할 커스텀 색상 목록 (예: 파랑, 초록, 빨강, 보라색의 다양한 톤) custom_colors = ['#1f77b4', '#2ca02c', '#d62728', '#9467bd'] 커스텀 색상을 사용하여 ListedColormap 생성 custom_cmap = ListedColormap(custom_colors) 그래프 크기 설정 plt.figure(figsize=(8, 6)) 커스텀 칼러맵을 사용하여 막대 그래프 생성 bars = plt.bar(categories, values, color=custom_cmap.colors) 제목 추가 plt.title('Bar Chart with Custom ListedColormap') 축 레이블 지정 plt.xlabel('Categories') plt.ylabel('Values') 그래프 표시 plt.show()

Matplotlib 커스텀 칼러맵을 사용한 ListedColormap. 저자 이미지.

LinearSegmentedColormap으로 커스텀 칼러맵 생성

LinearSegmentedColormap은 색상 간의 부드러운 전환을 생성할 수 있게 해줍니다. 이는 연속 데이터가梯도 색상 변화를 요구할 때 유용합니다. 여기서 저는 시각화에 사용할 구간 수를 지정하고 있습니다.

from matplotlib.colors import LinearSegmentedColormap 2D 가우시안 함수의 값 그리드 생성 x = np.linspace(-2, 2, 500) y = np.linspace(-2, 2, 500) X, Y = np.meshgrid(x, y) Z = np.exp(- (X**2 + Y**2)) 블루에서 白으로再到 빨강으로 전이되는 커스텀 컬러맵 정의 colors = ['blue', 'white', 'red'] custom_cmap = LinearSegmentedColormap.from_list('blue_white_red', colors) 컬러 클래스의 수를 조정 (이离散 수준) 레벨의 수를 지정 (예: 10개의 고유한 컬러 대) num_classes = 10 levels = np.linspace(Z.min(), Z.max(), num_classes) 그림 크기를 설정 plt.figure(figsize=(8, 6)) 조정된 컬러맵으로 2D 가우시안 함수 표시 contour = plt.contourf(X, Y, Z, levels=levels, cmap=custom_cmap) 디스크리트 컬러 클래스를 보여주는 컬러 바 추가 plt.colorbar(contour, label='Gaussian Function Value') 축에 레이블 추가 plt.xlabel('X') plt.ylabel('Y') 타이틀 추가 plt.title(f'2D Gaussian with {num_classes} Discrete Color Classes') 그래프 표시 plt.show()

Matplotlib 커스텀 컬러 클래스 수 조정. 작자 이미지.

컬러 범위와 강도 커스터마이징

기존의 컬러맵에서 색상의 강도나 범위를 제어하려면 그 정규화를 조작하거나 색상의 하위 집합을 사용하기 위해 자를 수 있습니다. 다음 예제에서는 색상 범위를 자르하여 16도에서 40도 사이의 온도를 표시합니다.

# 히트맵을 위한 플롯 설정 plt.figure(figsize=(12, 8)) # 온도 범위에 대한 사용자 정의 정규화 정의 norm = mcolors.Normalize(vmin=16, vmax=40) # 순차적 컬러맵을 사용하여 히트맵 생성 heatmap = plt.imshow(monthly_temperature_table, cmap='YlOrRd', aspect='auto', norm=norm) # 온도를 나타내는 컬러 바 추가 colorbar = plt.colorbar(heatmap, orientation='horizontal') colorbar.set_label('Temperature (°C)', labelpad=10) # 축을 레이블링 plt.xlabel('Day of the Month') plt.ylabel('Month') # y축 틱을 숫자 대신 월 이름으로 표시 plt.yticks(ticks=np.arange(len(month_names)), labels=month_names) # 히트맵에 제목 추가 plt.title('Monthly Temperature Heatmap (Sequential Colormap)') # 플롯 표시 plt.grid(False) plt.show()

Matplotlib 컬러 범위와 강도 사용자 정의. 저자 이미지.

기존 컬러맵 결합

기존의 컬러맵을 여러 개 섞어 더 복잡한 시각화를 만들 수도 있습니다.

from matplotlib.colors import LinearSegmentedColormap, Normalize # 합성 고도 데이터 생성 x = np.linspace(-180, 180, 500) # 경도 y = np.linspace(-90, 90, 250) # 위도 X, Y = np.meshgrid(x, y) Z = 5000 * np.sin(np.sqrt(X**2 + Y**2) * np.pi / 180) # 합성 고도 데이터 # 기본 컬러맵 정의 ('viridis'와 'cividis') cmap1 = plt.get_cmap('viridis') cmap2 = plt.get_cmap('cividis') # 두 개의 기본 컬러맵을 섞어 커스텀 컬러맵 생성 def blend_colormaps(cmap1, cmap2, blend_ratio=0.5): """Blend two colormaps together.""" c1 = cmap1(np.linspace(0, 1, 256)) c2 = cmap2(np.linspace(0, 1, 256)) blended_colors = (1 - blend_ratio) * c1 + blend_ratio * c2 return LinearSegmentedColormap.from_list('blended_cmap', blended_colors) # 섞은 컬러맵 생성 custom_cmap = blend_colormaps(cmap1, cmap2, blend_ratio=0.5) # 시각화를 위한 데이터 정규화 norm = Normalize(vmin=-5000, vmax=5000) # 그래프 크기 설정 plt.figure(figsize=(12, 6)) # 합성 고도 데이터를 섞은 컬러맵으로 표시 contour = plt.contourf(X, Y, Z, levels=100, cmap=custom_cmap, norm=norm) # 컬러 맵의 색상 매핑을 보여주는 컬러 바 추가 plt.colorbar(contour, label='Elevation (meters)') # 축 레이블 추가 plt.xlabel('Longitude') plt.ylabel('Latitude') # 제목 추가 plt.title('Geographical Elevation Data with Blended Colormap (Viridis + Cividis)') # 그래프 표시 plt.show()

Matplotlib에서 기존 컬러맵 결합. 저자의 그림.

컬러맵 반전에 사용되는 _r 접미사

Matplotlib에서 어떤 컬러맵도 _r 접미사를 추가하여 반전할 수 있습니다.

# 히트맵을 위한 플롯 설정 plt.figure(figsize=(12, 8)) # 컬러 범위에 대한 커스텀 정규화 생성 norm = mcolors.Normalize(vmin=16, vmax=40) # 순차적 컬러맵을 사용하여 히트맵 그리기 im = plt.imshow(monthly_temperature_table, cmap='YlOrRd_r', norm=norm, aspect='equal') # 수평 방향의 컬러 바 추가 cbar = plt.colorbar(im, orientation='horizontal', pad=0.1) cbar.set_label('Temperature (°C)', labelpad=10) # 축에 레이블 추가 plt.xlabel('Day of the Month') plt.ylabel('Month') # y 축의 틱을 숫자 대신 월 이름으로 표시 plt.yticks(ticks=np.arange(len(month_names)), labels=month_names) # 제목 추가 plt.title('Temperature Heatmap (Sequential Colormap)') # 플롯 표시 plt.show()

Matplotlib에서 컬러맵 반전에 사용되는 _r 접미사. 저자의 그림.

Matplotlib 컬러맵에서 자주 발생하는 오류 처리

Matplotlib에서 콜러맵을 사용할 때 작업 흐름에 영향을 미치는 오류를 만날 수 있습니다. 다음은 몇 가지 오류와 이를 해결하는 방법입니다.

AttributeError: module ‘matplotlib’ has no attribute ‘colormaps’

이 오류는 Matplotlib 3.4.0 이전 버전을 사용하여 matplotlib.colormaps에 접근할 때 발생합니다. 콜러맵 어트리뷰트는 Matplotlib 3.4.0에서 추가되었습니다. 이 오류를 해결하기 위해 먼저 아래 코드를 사용하여 Matplotlib 버전을 확인하세요.

import matplotlib print(matplotlib.__version__)

다음 pip 명령어를 사용하여 업그레이드하세요.

pip install --upgrade matplotlib

Matplotlib 버전 업그레이드에 문제가 발생하면, 다음 방법을 사용하여 콜러맵에 접근해 보세요.

plt.get_cmap('viridis') # 대신 matplotlib.colormaps['viridis']를 사용하지 말고

부적절한 색 할당

값이 기대 범위 밖에 위치하거나 콜ormap이 잘못 적용될 때 색상 할당이 잘못될 수 있습니다. 콜ormap이 연속 데이터용으로 설계되었지만 범주 데이터에 적용되거나 그 반대인 경우에도 색상 할당이 잘못될 수 있습니다.

데이터가 기대 범위 내에 있도록 항상 정규화하거나 확대/축소를 vmaxvmin 매개변수를 사용하세요.

import matplotlib.colors as mcolors # 샘플 온도 데이터셋 생성 data = np.random.rand(10, 10) * 100 # 데이터 범위를 데이터에 맞게 조정 # 콜ormap 범위로 데이터를 확대/축소하기 위한 색상 정규화 인스턴스 생성 norm = mcolors.Normalize(vmin=0, vmax=100) # 'viridis' 콜ormap과 지정된 정규화를 사용하여 히트맵 생성 plt.imshow(data, cmap='viridis', norm=norm, interpolation='nearest') plt.colorbar() plt.show()

보다 정밀한 제어를 위해서는 플롯 함수에서 boundariesnorm 매개변수를 명시적으로 정의할 수 있습니다.

시각적 이상 현상과 예상치 못한 결과

디스크리트 또는 낮은 해상도 데이터를 처리할 때, 불필요한 색상 대, 과도한 대비 또는 색상 누출이 발생할 수 있습니다. 이 문제는 데이터의 범위가 제한적이지만 연속형 컬러맵으로 표시되는 경우 발생합니다.

이 문제를 해결하려면 더 많은 데이터 포인트를 사용하거나 색상 수준의 개수를 조정하여 전환을 부드럽게 할 수 있습니다.

# 컬러맵의 빈 수를 증가시키기 cmap = plt.get_cmap('viridis', 256) plt.imshow(data, cmap=cmap)

적절한 경우 디스크리트 데이터를 처리하기 위해 컬러맵을 고정된 수준으로 나눌 수 있습니다.

cmap = plt.get_cmap('inferno', 10) # 컬러맵을 10개의 디스크리트 수준으로 나누기 plt.imshow(data, cmap=cmap)

시각화를 저장할 때 해상도를 조정하여 낮은 해상도 차트를 피할 수 있도록 디스플레이 설정을 확인하고 조정할 수 있습니다.

plt.savefig('plot.png', dpi=300) # 더 높은 해상도로 그래프를 저장하기

클리пп링으로 인한 색상 왜곡

데이터에 기대치를 벗어난 극단적인 값을 포함할 때 색상 이상이 발생합니다. 이는 데이터의 일부가 잘려나가고 색상 맵의 최소 또는 최대 색상으로 할당되는 결과를 초래합니다.

색상 이상을 피하고자 한다면, 데이터 범위에 맞게 색상 제한을 vminvmax를 사용하여 조정하여 잘림을 방지하세요.

plt.imshow(data, cmap='plasma', vmin=0, vmax=100)

또한 극단적인 값을 제외한 제한을 설정하여 이상치를 처리하기 위해 강건한 스케일링을 사용해야 합니다.

import numpy as np robust_vmin, robust_vmax = np.percentile(data, [2, 98]) # 극단적인 이상치를 제거하기 위해 백분위수 사용 plt.imshow(data, cmap='inferno', vmin=robust_vmin, vmax=robust_vmax)

3D 그래프에서 색상 맵이 올바르게 표시되지 않음

3D 표면에 데이터가 매핑되는 방식에 문제가 있을 경우, 색상 맵이 3D 시각화에서 올바르게 표시되지 않을 수 있습니다. 이 문제를 해결하기 위해 z축 데이터가 색상 맵의 기대 범위에 맞게 정규화되었는지 확인하고, z값의 전체 범위를 포착할 수 있는 적절한 색상 맵 제한을 사용하세요.

from mpl_toolkits.mplot3d import Axes3D 3D 표면 그래프를 위한 샘플 데이터 생성 X, Y = np.meshgrid(np.linspace(-5, 5, 50), np.linspace(-5, 5, 50)) Z = np.sin(np.sqrt(X**2 + Y**2)) 3D 축 객체 생성 ax = plt.axes(projection='3d') 'viridis' 콜ormap을 사용하여 표면을 그리며 색상 제한을 조정 ax.plot_surface(X, Y, Z, cmap='viridis', vmin=np.min(Z), vmax=np.max(Z)) plt.show()

결론

적절한 콜ormap 선택은 사용자가 데이터를 어떻게 보고 이해하는 데 큰 영향을 미치므로 중요한 단계입니다. 제 의견으로는, 데이터 분석에 많은 시간을 투자하면서도 마지막 단계에서는 부주의하다면, 즉 발견한 것을 전달하는 부분에서는 큰 실수라고 생각합니다.

幸운히, Matplotlib은 강력한 기능을 제공하여 시각화가 설득력 있게 전달될 수 있도록 합니다. 우리의 과정인 Matplotlib을 사용한 데이터 시각화 소개에 등록하여 전문가가 되세요. 또한, Python 사용자이자 시각화에 Seaborn을 사용하는 분들은 (두 가지를 모르는 것은 좋습니다) 우리의 Seaborn에서 색상 선택에 대한 빠른 가이드를 읽고 Seaborn을 사용한 데이터 시각화 소개 과정을 따라보세요.

Source:
https://www.datacamp.com/tutorial/matplotlib-colormaps