Pythonの
matplotlibはかなりの部分を自動でやってくれるので楽な反面、細かい調整が難しく、泥沼に陥って時間を浪費した挙句うまくいかないということがよくある。少しやってみて無理だと思ったら、とりあえず大体で作ってしまって、本当に細かいところはペイントなり何なりで調整するというのが合理的だと思う。大量の画像作成を自動化したいとか
matplotlibをマスターしたいという場合は別だが。
とかなんとかいいつつ自分も複数の図を上手く描くにはどうしたらよいのか気になっていたので色々調べてみた。
目次
+
複数のディスプレイで表示する
+
ひとつのディスプレイで表示する
+
Basemap()
+
共通のカラーマップを描く
plt.subplot()
先程から使われている
subplot() (
add_subplot())は、作図領域を縦横方向にそれぞれ等分するメソッドである。
例えば
plt.subplot(2,3,4)では領域を縦
2 横
3に分割し、その中の
4番目(
2行
1列目)を指定する。なお引数が全て1桁ならカンマは不要。
図の順番は上の行から左→右の方向に数えられる。
また順番は
1から始まるので、下の例のように書くときは
i+1とする必要があることに注意。
なお、一つのディスプレイにひとつの図を描く場合は
fig, ax = plt.subplots()
でよい。
fig = plt.figure()
ax = fig.add_subplot(111)
と同じである。
add_subplot()
作図領域を明示的に指示する場合は
add_subplot()を使う。
subplots_adjust() 余白を設定する
add_subplot()で作図領域を分割する場合、図の間の余白は
subplots_adjust()を使って設定する。
topと
bottomは下から、
leftと
rightは左からの長さを指定する。
wspaceと
hspaceはそれぞれ図の間の左右、上下のスペース。
デフォルト値は以下のとおり。
left :
0.125
right :
0.9
bottom:
0.1
top :
0.9
wspace:
0.2
hspace:
0.2
plt.axes()
plt.axes() では任意の位置に図を描くことができる。もちろん重ね合わせもできる。
plt.axes([left,bottom,width,height])
各値は
0.0~1.0の実数。
add_axes()
作図領域を明示的に指示する場合はこちらを使う。
前者では図の数が増えるとコードが汚くなってくるので後者の方がいいかも。
軸が出来たので、あとはこれまでと同じように描きたい図を描けばよい。
作図領域に図をひとつ描くときは次のように書くことが多いと思う(作図領域もひとつだけなら1行目も不要)。
では
add_subplot()や
add_axes()などを使って複数の軸を用意したとき、
Basemap()はどのように使えばよいのか?
結論から言うと、
Basemap()の引数に
axを指定する。
次のコードでは作図領域に2つの図を作成し、2つめにのみ
Basemap()を使って海岸線を描く。
これがかなり面倒くさい。
お世辞にもスマートとは言えないが、一応以下で作成は出来る。
説明が必要と思われるところ
cnorm = np.linspace(vmin,vmax,1000)
cnorml = colors.BoundaryNorm(cnorm,256)
色と値の対応を統一するため、
imshow()で
cmapと
normを指定する。
今回は連続のカラーマップにするため、最小値から最大値までを細かく分割した。
ax = fig.add_axes([0.1,0,0.8,0.4])
位置は適当にアタリを付けて、あとはカラーバーの位置を見ながら微調整という感じ。
ax.patch.set_facecolor('None')
描画領域がデフォルトだと白塗りなので色を無くす。
for loc in ['left','right','top','bottom']:
ax.spines[loc].set_visible(False)
目盛線を消す。
ax.tick_params(axis='x',top='off',bottom='off',labelbottom='off')
ax.tick_params(axis='y',left='off',right='off',labelleft='off')
目盛とラベルを消す。参考:
+
Python > Plotting > General > Axis
norm = colors.Normalize(vmin=vmin,vmax=vmax)
mappable = ScalarMappable(cmap=cmap,norm=norm)
mappable._A = []
カラーバー生成のときに
mappableなオブジェクト(意味はよくわからんがカラーマップ持ちのオブジェクト?)が要求されるので、それ用にダミーのオブジェクトを作る。カラーマップや分割の仕方はもちろん図と同じにする。
最後で何をしているのかは不明だが無いとエラーになる。
図本体を
add_subplot()で作ったが、カラーバーの位置と上手く合わせるには
add_axes()を使った方が楽かもしれない。