はじめに
matplotlibでbarプロットを行うと,Mappableオブジェクトが返ってこないため,カラーバーをつけることができない.
>>> import matplotli.pyplot as plt
>>> plt.bar(0, 1)
<Container object of 1 artists>
でも,なんとかしてカラーバーをつけたい!ということで,やってみた.
0. 適当なデータを作る
まず初めに,適当なデータを作ってみる.
ここでは,高さ1~3のバーを積み上げたような図を作成することを想定して,データを作る.
>>> import numpy as np
>>> dheight = np.random.choice([1, 2, 3], size=10)
>>> data = np.random.choice([1, 2, 3, 4, 5], size=dheight.size)
>>> print data
[1 1 1 4 5 2 1 2 2 4]
今回は,ここで作成したdataという変数の値に応じて色を付けていくということを行う.
適当なデータを作ったので,いよいよ作図に入る.
1. Normalize関数を作る
まず,matplotlibのカラーバーは,0~1の間の値に対応してカラーマップに色が定義されている.したがって,今回のような1~5の値に応じて色を塗りたい場合は,標準化するための関数(のようなオブジェクト)が必要となる.それを作成できるのが,Normalizeというクラスである.
>>> from matplotlib.colors import Normalize
>>> norm = Normalize(vmin=data.min(), vmax=data.max())
>>> print norm(1), norm(2), norm(3)
0.0 0.25 0.5
実際に値を入れてみると分かるように,このnormというオブジェクトに値を与えると,確かにvminが0,vmaxが1となるように標準化されている.
2. Mappableオブジェクトの作成
次に,Mappableオブジェクトを作成する.
今回は,matplotlibのデフォルトのカラーマップであるjetに合わせてMappableを作る.
>>> from matplotlib.cm import ScalarMappable, get_cmap
>>> cmap = get_cmap('jet')
>>> mappable = ScalarMappable(cmap=cmap, norm=norm)
>>> mappable._A = []
3. データをプロットする
ここまで準備ができたら,いよいよ実際にデータをプロットできる.
>>> import matplotlib.pyplot as plt
>>> bottom = 0.
>>> for dh, v in zip(dheight, data):
... plt.bar(0, dh, width=1, bottom=bottom, color=cmap(norm(v)))
... bottom += dh
>>> cbar = plt.colorbar(mappable)
今回プロットしたデータは[1 1 1 4 5 2 1 2 2 4]なので,この値に対応した色がカラーバーにあれば,問題なくカラーバーを描けたことになる.
4. ラベルを付ける
最後に,ラベルを付けて完成となる.
今回は,データの最小値から最大値の間を5つに区切ってラベルを貼り付けていく.
>>> cbar = plt.colorbar(mappable)
>>> ticks = np.linspace(norm.vmin, norm.vmax, 5)
>>> cbar.set_ticks(ticks)
>>> cbar.ax.set_yticklabels([str(s) for s in ticks])
[<matplotlib.text.Text at 0x7f36ac9b01d0>,
<matplotlib.text.Text at 0x7f36ac9bb850>,
<matplotlib.text.Text at 0x7f36ac98e550>,
<matplotlib.text.Text at 0x7f36ac98ec50>,
<matplotlib.text.Text at 0x7f36ac996390>]
5. 完成!
以上で完成である.
>>> plt.show()
無事,[1 1 1 4 5 2 1 2 2 4]の値に対応した色が描かれた.