matplotlibで自前のグラデーション色を作成してみる
前回、ETOPO1のグローバル地形データセットから作成した地球の全体地図を好みの色で色分けしたいと、NOAAの地球の全体地図の画像から、使われている色を取り出してみましたが
全ての色を手作業で、指定するのは、やってみると流石に骨が折れるので、代表となる標高地でのいくつかの色を指定してあげると、あとは、途中の標高値の色は線形補間で補いながら自前のグラデーションのカラーマップを作成するスクリプトを試しに作ってみました。
こんな感じ。
代表となる標高での色をnp.arrayの配列として与えてあげると
color = np.array([[-3000, '#0938BF'], [-1000, '#50D9FB'], [-1, '#C3EAF3'], [0, '#1F4806'], [100, '#83C979'], [300, '#F9EFCB'], [1000, '#E8BA55'], [2000, '#68552B'], [3000, '#FFFFFF']])
こんな感じのカラーマップを作成してくれます。
生成した自前のグラデーションを使うと、こんな感じで、地球全体を標高1m毎に塗り分けることも出来ます。
ソースは以下
#!/usr/bin/env python # -*- coding: utf-8 -*- import matplotlib.colors as clr import numpy as np from sklearn import preprocessing # 基点となる標高での色を配列として定義する color = np.array([[-3000, '#0938BF'], [-1000, '#50D9FB'], [-1, '#C3EAF3'], [0, '#1F4806'], [100, '#83C979'], [300, '#F9EFCB'], [1000, '#E8BA55'], [2000, '#68552B'], [3000, '#FFFFFF']]) # 標高値を0..1の範囲に正規化 colorindex = color[:, 0].astype(np.float32) colorindex = preprocessing.minmax_scale(colorindex) print colorindex # 正規化した標高値と各色の組みのリストcolornormを生成 colornorm = [] for no, norm in enumerate(colorindex): colornorm.append([norm, color[no, 1]]) print colornorm # colornormに従いグラデーションカラーマップを作成 cmap = clr.LinearSegmentedColormap.from_list('a', colornorm, N=6000) # 作成したカラーマップを画像表示してみる from PIL import Image im = Image.new('RGB', (6000, 500)) ld = im.load() for x in range(im.size[0]): r,g,b,a = (np.array(cmap(x))*256).astype('int16') for y in range(im.size[1]): ld[x, y] = (r, g, b) im.save('1.jpg') im.show()