matplotlibで綺麗な図を作りたい!!
データアナリストや研究者、エンジニアであれば、クライアント向け資料を作るときや論文を書く際に、このようなことは誰しも思うことでしょう。
かくいう私もまさにそのような状況です。
matplotlibはデフォルトでもある程度綺麗な図形を表現することができますが、colormapを用いることでより良い感じのグラフを作ることができます。
この記事ではmatplotlibで用意されている色の仕組みについて、またこれらを駆使して良い感じの図形やグラフを作るサンプルをいくつか紹介します。
- matplitlibのcolormap(cmap)の仕組みと構造を理解する
- colormapを用いて散布図を書く
colormapとは?仕組みと構造
colormapは、matplotlibが用意しているカラーマップのライブラリで、数値を色に変換することで、数字の傾向を可視化することができる仕組みです。
カラーマップはいくつもの種類があり、利用者は利用したい好きなカラーマップを選ぶことができますし、自分でカラーマップを作成することもできます。
代表的なものに、viridis、plasma、inferno、magma、cividisなどのカラーマップがあります。
これらはこのような値になっており、各カラーマップにおける色と値がこのように対応しています。

上のカラーバーを描くには、下記のようなコードを実装しました。
c_maps = ['viridis', 'plasma', 'inferno', 'magma', 'cividis', 'twilight']
fig, ax = plt.subplots(2, 3, figsize=(12, 2), dpi=100)
plt.tight_layout()
for idx, name in enumerate(c_maps):
row = idx // 3
col = idx % 3
cmap = mpl.colormaps[name]
fig.colorbar(mpl.cm.ScalarMappable(cmap=cmap), cax=ax[row, col], orientation='horizontal', label="{} colormap".format(name))
fig.colorbarメソッドに、cmapを指定したScalarMappableオブジェクトを渡すことでカラーバーを描くことができます。
colormapの値へのアクセス
colormapを用いることで、値から色、色から値への相互変換をすることができます。
もっぱら、データを可視化したい時には、値から色への変換をする際に利用することが多いと思います。colormapを利用して、値からカラーマップの色にアクセスするには、下記のように、カラーマップを指定し、さらに0~1の範囲に正規化したデータの値を指定することで、指定したカラーマップの色をRGB+(alpha)の値で得ることができます。

colormapを利用してグラデーションの図を描く
実際に、試してみましょう。今回は、回帰分析などでよく利用されている、カリフォルニアの住宅価格データセットを用いて散布図を書いてみましょう。詳しいデータセットの説明は、下記のリンクを参考にしてください。

下は、横軸が緯度(Latitude)で縦軸が経度(Longitude)にとった散布図です。散布図は2つありますが、右側がカラーマップを利用して、各点における人口(Population)を色で表現したものになります。
散布図においても、さらにその上に色情報を載せることで、情報をプラスすることができます。

このグラフを描くコードは下記になります。
ライブラリとデータのインポート
データセットの準備方法や各系列の解説は上述のリンクに掲載しているのでそちらをみてください。
import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
import matplotlib.cm as cm
from sklearn.datasets import fetch_california_housing
data_housing = fetch_california_housing()
train_x = pd.DataFrame(data_housing.data, columns=data_housing.feature_names)
train_y = pd.Series(data_housing.target)
散布図を描く
散布図を書きます。ここで、本来であればColormapには0~1の正規化した値を入れるのですが、cm.ScalarMappableオブジェクトを利用することで、これらの正規化をしています。
fig, axes = plt.subplots(1, 2, figsize=(10, 5), dpi=80)
cmap = cm.GnBu
norm = mpl.colors.Normalize(vmin=population.min(), vmax=population.max())
axes[0].set_xlabel("Lattitude")
axes[0].set_ylabel("Longitude")
axes[0].scatter(train_x["Latitude"], train_x["Longitude"], s=10)
axes[1].set_xlabel("Lattitude")
axes[1].set_ylabel("Longitude")
axes[1].scatter(train_x["Latitude"], train_x["Longitude"], s=10,
color=mpl.cm.ScalarMappable(norm=norm, cmap=cmap).to_rgba(train_x["Population"]))
