Matplotlibで既存のColormapをカスタムする
はじめに
Matplotlibのpcolorなどでカラーマップはよく使います。私はjetをよく使うのですが、「0のときに黒や白など色みのない色にしたい」など微調整したいときはしばしばあります。今回はその方法を調べたのでまとめておきます。
参考:Matplotlibで簡単に使えるカラーマップ
matplotlibのColormapオブジェクト
matplotlibのカラーマップはmatplotlib.cmライブラリ上でColormapオブジェクトとして管理されています。例えばjetのカラーマップは次のようにして生成できます。
mycmap = cm.jet
このColormapオブジェクトにはcallableであるという特徴があります。どういうことかというと、0から1.0までの値かそのリストを引数に与えると、0~1.0が値域になっているカラーバーで対応する色をRGBAで出力してくれます。
# 例:値0.5に対応するjetの色がmycolorに入る mycolor = mycmap(0.5)
またColormap自体は色のリストから生成することができます。jetのような連続的な分布をするカラーマップはLinearSegmentedColormap.from_list関数で生成できます。LinearSegmentedColormapでは
離散的に色をいくつか与えても自動的に補完してくれます。したがって、任意のカラーマップからいくつかの色をサンプリングしてfrom_list関数に与えればカラーマップを再構成することができます。この再構成する前の色のリストをいじることで、カスタマイズしたカラーマップを得ることができる、というわけです。
今回はjetの0のところを黒にしたいので、サンプリングした色のリストのうち0に対応する部分を黒に置き換えて再構成します
サンプルコード
n_base = 10 # サンプリングする個数 base_cmap = cm.jet new_colors = base_cmap(np.linspace(0,1.0,n_base)) new_colors[0] = [0,0,0,1] #一番最初を黒(#000000, アルファ値1)にする # 色のリストから新たなカラーマップの生成 mycmap = colors.LinearSegmentedColormap.from_list("mycmap",new_colors)
サンプリング数ですが少なすぎると黒に引きずられて全体が暗くなり、多すぎると黒い領域が少なすぎてうまく設定できません。経験則ですが等間隔で取るならば10くらいがちょうどよいでしょう*1。
こうして得られたmycmapは他のカラーマップと同様にpcolorなどで使うことができます。
c = myax.pcolor(xx, yy, zz, shading="auto",cmap=mycmap)
補足
本記事は生成AI(Copilot)を用いて得たサンプルコードをヒントに用いています。
参考文献
- 【python】matplotlib.cmの使い方を説明しようと思う
https://hayataka2049.hatenablog.jp/entry/2018/05/26/103000 - 【Python】matplotlibによるグラフ描画時のColormapのカスタマイズ
https://qiita.com/kenmatsu4/items/fe8a2f1c34c8d5676df8 - matplotlibで色をグラデーション的に選択
https://qiita.com/hokekiyoo/items/cea310b2c36a01b970a6
*1:なお今回はnp.linspaceで与えているので等間隔になっていますが、サンプリングの仕方を工夫すればもうちょっと調整できる余地があります。