[matplotlib] colorbarを図と同じサイズにする方法。

matplotlibのcolorbarが、図のサイズと一致しないことがあります。同じサイズにする方法を紹介します。

matplotlibのバージョンは3.3.3です。次のcolorbarのドキュメント日本語訳なども参考にしてみてください。

colorbarのサイズがずれる例と原因

colorbarのサイズがずれるのは、例えば次のような場合です。

import matplotlib.pyplot as plt

dat = [[0,1,2,3,4,5,],
       [6,7,8,9,10,11,],
       [12,13,14,15,16,17,],]
fig, ax = plt.subplots()
aximg = ax.imshow(dat)

fig.colorbar(aximg, ax=ax)
plt.show()

(これはオブジェクト指向スタイルです。pyplotスタイルでは、plt.colorbar()などとしますが同じ結果になります。)

なぜこういうことが起こるかと言うと、axesと図(マップ)のアスペクト比が異なるためです。imshow()やmatshow()がマップを描画するときは、デフォルトでは各マスが正方形になるようにアスペクト比を決めており、axesのアスペクト比に合わせるわけではありません。一方で、colorbarはパラメータとして渡されたaxesだけを見て高さを決めるために、図の高さとズレが生じるというわけです。

colorbarのサイズをあわせる方法 その1

アブストの提出締め切りが1時間後に迫っているというときや、サイズをあわせるのは最初で最後というときには、次のようにcolorbar()にshrinkパラメータを渡してcolorbarのサイズを手動で調整するのが早いです。

colorbar(mappable, ax=ax, shrink=0.5) #colorbarのサイズを縦横0.5倍にする。

先程の例でshrinkを使うと次のようになります。

import matplotlib.pyplot as plt

dat = [[0,1,2,3,4,5,],
       [6,7,8,9,10,11,],
       [12,13,14,15,16,17,],]
fig, ax = plt.subplots()
aximg = ax.imshow(dat)

fig.colorbar(aximg, ax=ax, shrink=0.62)
plt.show()

0.62倍にすると高さがあいました。colorbarの横幅も狭くなっていますが、初見の人が気になるほどではありません。aspectパラメータ(デフォルトは20)を渡すと横幅を大きくすることもできます。

colorbarのサイズをあわせる方法 その2

時間に余裕があるときに通常選択すべきもう少し賢い方法は、colorbarに図と同じ高さのaxesを渡すという方法です。

それには、まずmpl_toolkits.axes_grid1.axes_divider.make_axes_locatable()という関数にaxesを渡します。するとmpl_toolkits.axes_grid1.axes_divider.AxesDividerのインスタンスが返ります。

divider = make_axes_locatable(axes)

そして次のようにAxesDivider.append_axes()メソッドを使用すると、axesに隣り合う新しいaxesを作成できます。

cax = divider.append_axes("right")

最後に、新しいaxesをcolorbarのcaxパラメータ(axではない)に渡すと、そのaxesの全体を占めるようにcolorbarが描画されるというわけです。

fig.colorbar(aximg, cax=cax)

 

新しいaxesが元のaxesのどの位置に隣り合うかは、[“left”|”right”|”bottom”|”top”]から選ぶことができ、append_axes()に渡します。新しく作成されるaxesの高さまたは幅は、元のaxesに自動で合わせられます。

append_axes()のドキュメントには次のように書かれています。

append_axes(self, position, size, pad=None, add_to_figure=True, **kwargs)

Create an axes at the given position with the same height (or width) of the main axes.

position: [“left”|”right”|”bottom”|”top”]
size and pad should be axes_grid.axes_size compatible.

新しいaxesの幅または高さはsizeパラメータで指定し、axesの間に隙間を作りたい場合にはpadパラメータを渡します。

 

文章で説明するとややこしいですから、実際に使ってみましょう。

import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable #インポート

dat = [[0,1,2,3,4,5,],
       [6,7,8,9,10,11,],
       [12,13,14,15,16,17,],]
fig, ax = plt.subplots()
aximg = ax.imshow(dat)

divider = make_axes_locatable(ax) #axに紐付いたAxesDividerを取得
cax = divider.append_axes("right", size="5%", pad=0.1) #append_axesで新しいaxesを作成

fig.colorbar(aximg, cax=cax) #新しく作成したaxesであるcaxを渡す。
plt.show()

この例では、append_axes(“right”, size=”5%”, pad=0.1)としました。図を描画しているaxesの右側(right)に、高さは同じで幅(size)は5%の新しいaxesを作成し、隙間(pad)を0.1あけて設置させました。

そして、colorbar(mappable, cax=cax)としてcaxパラメータに新しく作ったaxes(cax)を渡して、cax全体にカラーバーを表示させました。なお最初の例ではcolorbar(mappable, ax=ax)というように、axパラメータにaxesを渡していたため、axesの一部を使用してcolorbarが描画されていました。

この方法では、横幅も隙間も簡単に調整することができますので、コード量は増えますが綺麗な図を作ることができます。論文に載せる図などは、この方法で綺麗に作るのがおすすめです。

 

なお、図の上または下にカラーバーを表示するときには、append_axesで”top”や”bottom”をそれぞれ指定しますが、その時はカラーバーも横向きになるように回転させる必要があります。回転させるには、colorbarにorientation=’horizontal’を追加します。

import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable

dat = [[0,1,2,3,4,5,],
       [6,7,8,9,10,11,],
       [12,13,14,15,16,17,],]
fig, ax = plt.subplots()
aximg = ax.imshow(dat)

divider = make_axes_locatable(ax)
cax = divider.append_axes("bottom", size="5%", pad=0.5) #カラーバーを下に表示

fig.colorbar(aximg, cax=cax, orientation='horizontal') #カラーバーを回転
plt.show()

横向きのカラーバーが図の下に表示されました。

まとめ

matplotlibのcolorbarが、図のサイズと一致しないことがありますが、解決方法を二通り紹介しました。

make_axes_locatableあたりの関数はドキュメントが十分に整備されていませんが、こう書くものと覚えておけばよいでしょう。気になる場合はソースコードを読むと動作がなんとなくわかります。

matplotlibのドキュメントはわかりにくいですが、この記事が参考になりましたら幸いです。

次の記事も参考にしてみてくださいね。

 

以上、matplotlibのcolorbarを図と同じサイズにする方法。でした。

参考