プログラム日記φ(..)

おもにPython関係のプログラムメモ

matplotlibで自前のグラデーション色を作成してみる

前回、ETOPO1のグローバル地形データセットから作成した地球の全体地図を好みの色で色分けしたいと、NOAAの地球の全体地図の画像から、使われている色を取り出してみましたが

 

memomemokun.hateblo.jp

 

全ての色を手作業で、指定するのは、やってみると流石に骨が折れるので、代表となる標高地でのいくつかの色を指定してあげると、あとは、途中の標高値の色は線形補間で補いながら自前のグラデーションのカラーマップを作成するスクリプトを試しに作ってみました。

 

こんな感じ。

 

代表となる標高での色をnp.arrayの配列として与えてあげると

color = np.array([[-3000, '#0938BF'],
                 [-1000,  '#50D9FB'],
                 [-1,     '#C3EAF3'],
                 [0,      '#1F4806'],
                 [100,    '#83C979'],
                 [300,    '#F9EFCB'],
                 [1000,   '#E8BA55'],
                 [2000,   '#68552B'],
                 [3000,   '#FFFFFF']])

 

 

 こんな感じのカラーマップを作成してくれます。 

matplotlibで自前のグラデーション色を作成する。

matplotlibで自前のグラデーション色を作成する。

 

生成した自前のグラデーションを使うと、こんな感じで、地球全体を標高1m毎に塗り分けることも出来ます。

f:id:memomemokun:20190925141530j:plain

memomemokun.hateblo.jp

 

ソースは以下

#!/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()