グラフに一致するようにMatplotlibカラーバーサイズを設定する


160

このようなimshowグラフのカラーバーをグラフと同じ高さにすることはできません。実際にPhotoshopを使用するまでは。高さを一致させるにはどうすればよいですか?カラーバーのサイズの不一致の例



@ imjohns3その投稿では、カラーバーに対して何もしないようです。何を設定しても同じサイズのままです。ただし、分数と縮小を設定すると、カラーバーは同じままでグラフのサイズが変化し、すでにある状態に戻るまで何も実行されなくなります。
Elliot

ドキュメントを確認してください-matplotlib.org/api/colorbar_api.html-そして、fractionまたはshrinkargs を使用してください。
BoltzmannBrain

回答:


194

これは、matplotlib AxisDividerを使用して簡単に行うことができます。

リンクされたページの例は、サブプロットを使用しなくても機能します。

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

plt.figure()
ax = plt.gca()
im = ax.imshow(np.arange(100).reshape((10,10)))

# create an axes on the right side of ax. The width of cax will be 5%
# of ax and the padding between cax and ax will be fixed at 0.05 inch.
divider = make_axes_locatable(ax)
cax = divider.append_axes("right", size="5%", pad=0.05)

plt.colorbar(im, cax=cax)

ここに画像の説明を入力してください


1
私はサブプロットの中で働いていないので、これは当てはまりません。
Elliot

いじくり回した後、それを機能させました。subplot_adjustとのやり取りに多くの問題があり、相互に関連する適切な場所で呼び出しを取得する必要があります。
Elliot

11
これにより、グラフのサイズが若干変更されます。2x2グリッドに4つありますが、右側の2つだけにバーを配置します(行ごとにスケールが適用されます)。ただし、これによりサイズが異なります。私は(divider呼び出しを使用して)colorbar呼び出しを行わないようにしただけですが、もちろんこれにより、空の白いボックスと数字が側面に残ります。それらすべてにバーを配置せずに、それらを一定のサイズにするにはどうすればよいですか?
Elliot

@bogatron残念ながら、これは投影された軸では機能しません
Bogdan

を使用してタイトルを追加する場合はplt.title、右側に入れ替えて表示されます。これを克服する方法はありますか?
user2820579 2017

224

この組み合わせ(およびこれらに近い値)は、「魔法のように」機能して、ディスプレイのサイズに関係なく、カラーバーをプロットに合わせてスケーリングし続けるように見えます。

plt.colorbar(im,fraction=0.046, pad=0.04)

また、プロットを正方形から外せる軸を共有する必要もありません。


4
これは場合によっては機能するかもしれませんが、一般的には機能しません。たとえば、幅が高さの2倍の元の質問のようなものをプロットしてみてください。
Matthias

プロットの高さに一致するようにスケーリングされている場合、分数オプションは、あなたが言及する場合でもまだ機能するようです。(mpl v1.4.3)
スカイテイカー2015年

6
これが唯一の普遍的な方法です。axex_grid1を使用したソリューションは、GeoAxesなどの投影された軸では機能しません。
Bogdan

OMGこれは素晴らしいです。解決策をありがとうございました
2D_

3
@Matthiasコメントへの応答。このトリックを使用して、画像が広すぎる場合を修正できます。画像はim_ratio = data.shape[0]/data.shape[1] plt.colorbar(im,fraction=0.046*im_ratio, pad=0.04)どこですかdata
eindzl 2018年

29

@bogatron は、適切な高さを生成するmatplotlib docsによって提案された回答をすでに提供していますが、別の問題が発生します。これで、カラーバーの幅(およびカラーバーとプロットの間のスペース)がプロットの幅とともに変化します。つまり、カラーバーのアスペクト比は固定されなくなりました。

適切な高さ特定のアスペクト比の両方を取得するには、神秘的なaxes_grid1モジュールをもう少し深く掘る必要があります。

import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable, axes_size
import numpy as np

aspect = 20
pad_fraction = 0.5

ax = plt.gca()
im = ax.imshow(np.arange(200).reshape((20, 10)))
divider = make_axes_locatable(ax)
width = axes_size.AxesY(ax, aspect=1./aspect)
pad = axes_size.Fraction(pad_fraction, width)
cax = divider.append_axes("right", size=width, pad=pad)
plt.colorbar(im, cax=cax)

これは、プロットの高さに対するカラーバーのを指定することに注意してください(以前の図のとは対照的です)。

カラーバーとプロットの間隔は、カラーバーの幅の一部として指定できるようになりました。これは、図の幅の一部よりもはるかに意味のある数値です。

カラーバー付きの画像プロット

更新:

このトピックIPythonノートブックを作成しまし。ここでは、上記のコードを簡単に再利用できる関数にパックしました。

import matplotlib.pyplot as plt
from mpl_toolkits import axes_grid1

def add_colorbar(im, aspect=20, pad_fraction=0.5, **kwargs):
    """Add a vertical color bar to an image plot."""
    divider = axes_grid1.make_axes_locatable(im.axes)
    width = axes_grid1.axes_size.AxesY(im.axes, aspect=1./aspect)
    pad = axes_grid1.axes_size.Fraction(pad_fraction, width)
    current_ax = plt.gca()
    cax = divider.append_axes("right", size=width, pad=pad)
    plt.sca(current_ax)
    return im.axes.figure.colorbar(im, cax=cax, **kwargs)

次のように使用できます。

im = plt.imshow(np.arange(200).reshape((20, 10)))
add_colorbar(im)

1
これは本当に役立つ小さな機能です!警告の1言は、複数のカラーバーを重ねて表示したい場合、それらが重なって表示されるため機能しないことです。
David Hall

22

上記のすべての回答に感謝します。いくつかの回答やコメントが指摘したようにしかし、axes_grid1モジュールはアドレスGeoAxesは、調整に対しすることはできませんfractionpadshrink、および他の類似のパラメータは必ずしも本当に私を気に非常に正確な順序を与えることはできません。私は、colorbarそれ自体を与えることは、axes言及されているすべての問題に対処するためのより良い解決策であると信じています。

コード

import matplotlib.pyplot as plt
import numpy as np

fig=plt.figure()
ax = plt.axes()
im = ax.imshow(np.arange(100).reshape((10,10)))

# Create an axes for colorbar. The position of the axes is calculated based on the position of ax.
# You can change 0.01 to adjust the distance between the main image and the colorbar.
# You can change 0.02 to adjust the width of the colorbar.
# This practice is universal for both subplots and GeoAxes.

cax = fig.add_axes([ax.get_position().x1+0.01,ax.get_position().y0,0.02,ax.get_position().height])
plt.colorbar(im, cax=cax) # Similar to fig.colorbar(im, cax = cax)

結果

ここに画像の説明を入力してください

後で、matplotlib.pyplot.colorbar公式ドキュメントにaxオプションが表示されます。これは、カラーバー用のスペースを提供する既存の軸です。したがって、これは複数のサブプロットに役立ちます。以下を参照してください。

コード

fig, ax = plt.subplots(2,1,figsize=(12,8)) # Caution, figsize will also influence positions.
im1 = ax[0].imshow(np.arange(100).reshape((10,10)), vmin = -100, vmax =100)
im2 = ax[1].imshow(np.arange(-100,0).reshape((10,10)), vmin = -100, vmax =100)
fig.colorbar(im1, ax=ax)

結果

ここに画像の説明を入力してください

繰り返しますが、私の観点からより正確な方法であるcaxを指定することで、同様の効果を得ることができます。

コード

fig, ax = plt.subplots(2,1,figsize=(12,8))
im1 = ax[0].imshow(np.arange(100).reshape((10,10)), vmin = -100, vmax =100)
im2 = ax[1].imshow(np.arange(-100,0).reshape((10,10)), vmin = -100, vmax =100)
cax = fig.add_axes([ax[1].get_position().x1-0.25,ax[1].get_position().y0,0.02,ax[0].get_position().y1-ax[1].get_position().y0])
fig.colorbar(im1, cax=cax)

結果

ここに画像の説明を入力してください


@ HS-nebulaコメントありがとうございます。楽しんでいただけてうれしいです。:)
Fei Yao

本当に素晴らしい答え。ありがとうございました!!
エピソード

11

colorbar分数や縮小パラメータを使用してトライを作成するとき。

ドキュメントから:

分数0.15; カラーバーに使用する元の軸の割合

縮小1.0; カラーバーを縮小する割合


1
縮小1.0と分数を任意に設定した場合、分数を変更するとそれがすでにあるものになり、変更すると何も実行されなくなるまで、グラフは縮小され、カラーバーのサイズにはまったく影響しません。
Elliot

それらを正確にどこに指定するかは、colorbar()関数またはメソッドへのパラメーターでなければなりません。
スティーブバーンズ

ありがとう。縮小パラメータを指定するだけで、魔法のように機能します。
CodingNow

11

上記のすべての解決策は良いですが、@ Steveと@bejotaは、派手な呼び出しを必要とせず、普遍的であるため、最高です。

ユニバーサルとは、を含むあらゆるタイプの軸で機能することを意味しGeoAxesます。たとえば、マッピング用に投影された軸があるとします。

projection = cartopy.crs.UTM(zone='17N')
ax = plt.axes(projection=projection)
im = ax.imshow(np.arange(200).reshape((20, 10)))

への呼び出し

cax = divider.append_axes("right", size=width, pad=pad)

失敗します: KeyException: map_projection

したがって、すべてのタイプの軸でカラーバーサイズを処理する唯一の一般的な方法は次のとおりです。

ax.colorbar(im, fraction=0.046, pad=0.04)

0.035から0.046までの割合で作業して、最適なサイズを取得します。ただし、フラクションとパディグの値は、プロットに最適になるように調整する必要があり、カラーバーの向きが垂直位置か水平位置かによって異なります。


1
また、追加することができshrinkたときにパラメータをfraction一緒にpad十分な望ましい結果が得られていません。
Fei Yao
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.