Matplotlibのカラemap:カラースキームのカスタマイズ

データ可視化は、データアナリストやデータサイエンティストが複雑な情報を表現し、意味のある洞察を生成するための最良の方法の1つ(もしくは最良の方法)です。ステークホルダーとのコミュニケーション機会を最大限に活かすために、Matplotlibのカラーマップに関する役立つ情報をまとめました。

この記事で見ていただくように、Matplotlibは非常に柔軟で拡張性のあるPythonの可視化ライブラリです。シンプルなチャートから完全なインタラクティブなビジュアルまで、すべてのオプションを提供しています。Pythonに慣れていない場合は、始める前に私たちのPython入門コースを受講して基礎を理解することをお勧めします。個人的には、Pythonチートシートをすぐ手元に置いています。これはよく使う関数の参考に役立ちます。

適切なMatplotlibカラーマップの選択

最初に考えるべきことの一つは、順序型、分岐型、もしくは分類型のカラーマップの選択です。カラーマップを選ぶ際に考慮すべき他の重要な要素には、知觉的な均一性が含まれます。これは、データ値の等しい差が色の等しい差として知觉されることを意味します。また、視覚障害者にやさしいカラーマップオプションを使用して、すべての視聴者にアクセス可能な視覚を提供することも重要です。

カラーマップを選ぶ際には、異なるドメインの標準も考慮するべきです。例えば、海洋学の研究では、青色の異なる濃淡が異なる水深を表しています。視覚化に適したカラーマップがわからない場合は、さまざまなツールやリソースが利用できます。特に、私たちの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軸のタイトルを非表示にする(行が1行のみのため) # タイトルを追加 plt.title('Profit/Loss Heatmap (Diverging Colormap)') # 表示のためにレイアウトを調整 plt.tight_layout() # プロットを表示 plt.show()

Matplotlib 分岐カラーマップの可視化例。作者による画像。

循環カラーマップ

循環カラーマップは、角度や波の位相、または時間帯などの繰り返しまたは循環パターンを表すデータを視覚化するのに役立ちます。循環カラーマップの使用例としては、周期関数(例えば、正弦波)の位相を視覚化することがあります。

# 正弦波のデータを作成 x = np.linspace(0, 2 * np.pi, 100) # 0から2πまでのX値(1つの完全なサイクル) y = np.sin(x) # Y値(Xの正弦) # フィグjureと軸を作成 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'] # 手動で選択した色の16進コード # パイチャートを作成 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の視覚的に均一なカラormapの可視化例。作者による画像。

Matplotlibカラormapの作成と修正

Matplotlibには多種多様なビルトインカラormapがありますが、カスタマイズしたい色のシナリオもあります。Matplotlibでカスタムカラormapを作成するための主要なツールはListedColormapLinearSegmentedColormapです。

ListedColormapでカスタムカラormapの作成

ListedColormapは、特定の色のリストからカラormapを作成することを許可します。この方法は、カテゴリデータの異なるカテゴリに特定の色を割り当てる場合に役立ちます。

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 2次元ガウシアン関数の値のグリッドを作成する 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個の異なる色の帯のための10) num_classes = 10 levels = np.linspace(Z.min(), Z.max(), num_classes) 図のサイズを設定する plt.figure(figsize=(8, 6)) 調整されたカラーマップで2次元ガウシアン関数をプロットする 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カスタムで色のクラス数を調整する。作者の画像。

色の範囲と強度をカスタマイズする

既存のカラーマップの強度や色の範囲を manipulate することで、その正規化を操作したり、利用可能な色のサブセットを使用するためにスライスすることができます。以下の例では、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') # 2つの基本カラーマップを混色してカスタムカラーマップを作成する 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) # フィigureのサイズを設定する 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) # 連続的なカラーマップを使用してimshowでヒートマップをプロットする 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']

不正な色の割り当て

あなたは、期待される範囲外の値を渡す場合や、カラーマップが適用される際に誤りが生じる場合に、 incorrect color assignments(正しくない色の割り当て)を経験するかもしれません。また、カラーマップが連続データ用のものであるのに分類データに適用されたり、その逆の場合にも incorrect color assignments が発生する可能性があります。

データが期待される範囲内であることを確認するために、常に vmax 以及び vmin パラメータを使用してデータを正規化またはスケーリングしてください。

import matplotlib.colors as mcolors # サンプルの温度データセットを作成する data = np.random.rand(10, 10) * 100 # データに合わせて範囲を調整する # カラーマップの範囲にデータをスケーリングするために色の正規化インスタンスを作成する norm = mcolors.Normalize(vmin=0, vmax=100) # 'viridis' カラーマップを使用して指定された正規化でヒートマップを作成する plt.imshow(data, cmap='viridis', norm=norm, interpolation='nearest') plt.colorbar() plt.show()

より細かい制御のためには、プロット関数内で boundaries または norm パラメータを使用して色の境界を明示的に定義することができます。

視覚的なアーティファクトと予期しない結果

離散的なデータや低解像度のデータを扱う際に、意図しない色の帯、過度の対照度、または色の漏れが発生することがあります。この問題は、データの範囲が限られているものが連続的な色のマップで表示される際に起こります。

この問題を解決するためには、より多くのデータポイントを使用するか、色のレベル数を調整して遷移をスムーズにする必要があります。

# カラーマップのビン数を増やす 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) # 高解像度でフィギュアを保存する

クリッピングによる色の変形

データに予想外の色範囲を超える極端な値が含まれると、色変形が発生します。これにより、データの一部がクリップされ、カラーマップの最小または最大色に割り当てられます。

色変形を避けるためには、データの範囲に合わせてvminおよびvmaxを使用して色の限界を調整し、クリップを防止します。

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