pythonで図を作成するとき,既存のcolormapを良く使用しますね.
普段は特に問題なく使用しているのですが,既存のcolormapを不連続にして使用したい時があります.
調べたところ,自作のcolormapを作成するのはたくさん載っていたんですが,ドンピシャのやり方がありませんでした.
色々調べた結果,できるようになったので簡単にまとめます.
今回はscatter
でこの操作をしたかったので,それを載せます.
他のコマンドについては,自身で調べてみてください.
応用すれば使えると思いますが…
まず,調べた中で一番多かった方法を紹介します.
とりあえずは以下のページを参考にしました.
コマンドはmatplotlib.colors.listedColormap
を使用します.
テストコードは以下の通りです.
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap, BoundaryNorm
#
# データ作成
x = np.arange(0,101,1)
y = np.arange(0,101,1)
value = np.arange(0,101,1)
# カラーマップ作成
cmap = ListedColormap(['red','blue','green','yellow'])
bounds = np.linspace(0,100,5)
norm = BoundaryNorm(bounds,cmap.N)
# プロット
plt.figure()
sc = plt.scatter(x,y,c=value,cmap=cmap,norm=norm,\
vmin=min(bounds),vmax=max(bounds) )
cbar = plt.colorbar(sc,aspect=30,shrink=0.7)
plt.show()
行っていることは,
これを行うとできるのが下の図です.
簡単ですね.
BoundaryNorm
はbounds
が等間隔でないの時に力を発揮します.
横のカラーバーに注目すると値は等間隔ではありませんが,バーの間隔は等間隔で見やすくなっています.(下に例を表示)
# 12行目のみを変更
bounds = [0, 10, 40, 85, 100]
さあ,本題に入りましょう.
調べた当初,ListedColormap
の引数を,既存のcolormapにすればいいのではと考えて,
cmap = ListedColormap(cm.viridis)
としていたのですが,まあうまくいきません.
色を自分で直接入力して作成することも過去に行ったことがありましたが,その都度カラーバーの色を検索して手入力は非常にだるいし,汎用性がありません.
そこで,
colormapのカラーコードを自動で調べてくれる機能があれば,できるのでは?
と思ったので,調べました.
そして,以下のサイトを見つけたのです!!
1つ目は色は16進数で指定することができること,2つ目はcolormapの色の16進数を抽出できることが示されています.
主に,2つ目が重要ですので読んでみてください.
以下にサンプルコードを示します(といってもほぼ写しですが).
import matplotlib.cm as cm
from matplotlib.colors import rgb2hex
cmap = cm.get_cmap('viridis',4) #colormapと分割数の指定
for i in range(cmap.N):
rgb = cmap(i)[:3]
print(rgb2hex(rgb))
出力:
#440154
#31688e
#35b779
#fde725
これによって簡単にカラーコードを調べることができます.
いよいよ実装する時が来ました.
1と2を組み合わせて,1つのコードにしましょう.
使い勝手がいいので,def
を用いて書きました.
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm
from matplotlib.colors import ListedColormap, BoundaryNorm, rgb2hex
def main():
# カラーコードの入手(→ 2)
colorname = 'viridis'
num = 5
color_code = get_color_code(colorname,num)
# データ作成
x = np.arange(0,101,1)
y = np.arange(0,101,1)
value = np.arange(0,101,1)
# カラーマップ作成(→ 1)
cmap = ListedColormap(color_code)
#bounds = np.arange(0,101,20)
bounds = [10,30,60,70,90]
norm = BoundaryNorm(bounds,cmap.N)
# 作図
plt.figure()
sc = plt.scatter(x,y,c=x,cmap=cmap,norm=norm, \
vmin=min(bounds),vmax=max(bounds))
cbar = plt.colorbar(sc,aspect=30,shrink=0.7)
plt.show()
return
def get_color_code(cname,num):
cmap = cm.get_cmap(cname,num)
code_list =[]
for i in range(cmap.N):
rgb = cmap(i)[:3]
print(rgb2hex(rgb))
code_list.append(rgb2hex(rgb))
return code_list
if __name__ == '__main__':
main()
組み合わせる際に重要なのは8~10行目,32~42行目です.
get_color_code
の説明を簡単にします.
2の出力されたカラーコードをlist
として保存して,main
コードに戻しています.
入出力の引数は以下の通り.
引数名 | データ型 | 入出力 |
---|---|---|
cname | str | 入力 |
num | int | 入力 |
code_list | list(要素はstr) | 出力 |
出力された図は以下の通りです.
ちゃんとvirides
を不連続にできてますね,成功です.
今回は散布図のカラーマップに使う,不連続カラーマップの作成の仕方をまとめました.
冒頭でも述べている通り,作成したカラーマップは他のコマンド(imshow
やplot
)にも応用可能だと思いますので,試してみてください.
Python