web-dev-qa-db-ja.com

matplotlibの図の凡例を配置および整列する方法は?

2行1列の2つのサブプロットを持つ図があります。見栄えの良い図の凡例を追加できます

fig.legend((l1, l2), ['2011', '2012'], loc="lower center", 
           ncol=2, fancybox=True, shadow=True, prop={'size':'small'})

ただし、この凡例はfigureの中心に配置されており、axesの中心の下には配置されていません。これで、軸座標を取得できます

axbox = ax[1].get_position()

そして理論的には、タプルでlocキーワードを指定することで凡例を配置できるはずです:

fig.legend(..., loc=(axbox.x0+0.5*axbox.width, axbox.y0-0.08), ...)

これは動作します除く凡例は左揃えであるため、locは凡例ボックスの左エッジ/コーナーを指定し、センター。 alignhorizo​​ntalalignmentなどのキーワードを検索しましたが、見つかりませんでした。また、「凡例の位置」を取得しようとしましたが、凡例には* get_position()*メソッドがありません。 * bbox_to_anchor *について読みましたが、図の凡例に適用すると意味がわかりません。これは、軸の凡例用に作成されたようです。

または:代わりにシフトされた軸の凡例を使用する必要がありますか?しかし、そもそもなぜフィギュアの伝説があるのでしょうか? loc = "lower center"も図の凡例を「中央に揃える」ことができる必要があります。

助けてくれてありがとう、

マーティン

20
maschu

この場合、Figure legendメソッドに軸を使用できます。いずれの場合も、bbox_to_anchorがキーです。既にお気づきのとおり、bbox_to_anchorは、凡例を配置する座標のタプル(またはボックス)を指定します。 bbox_to_anchorを使用している場合、location kwargを水平および垂直方向の配置を制御していると考えてください。

違いは、座標のタプルが軸または図座標として解釈されるかどうかだけです。

図の凡例を使用する例として:

import numpy as np
import matplotlib.pyplot as plt

fig, (ax1, ax2) = plt.subplots(nrows=2, sharex=True)

x = np.linspace(0, np.pi, 100)

line1, = ax1.plot(x, np.cos(3*x), color='red')
line2, = ax2.plot(x, np.sin(4*x), color='green')

# The key to the position is bbox_to_anchor: Place it at x=0.5, y=0.5
# in figure coordinates.
# "center" is basically saying center horizontal alignment and 
# center vertical alignment in this case
fig.legend([line1, line2], ['yep', 'nope'], bbox_to_anchor=[0.5, 0.5], 
           loc='center', ncol=2)

plt.show()

enter image description here

Axesメソッドの使用例として、次のようなものを試してください。

import numpy as np
import matplotlib.pyplot as plt

fig, (ax1, ax2) = plt.subplots(nrows=2, sharex=True)

x = np.linspace(0, np.pi, 100)

line1, = ax1.plot(x, np.cos(3*x), color='red')
line2, = ax2.plot(x, np.sin(4*x), color='green')

# The key to the position is bbox_to_anchor: Place it at x=0.5, y=0
# in axes coordinates.
# "upper center" is basically saying center horizontal alignment and 
# top vertical alignment in this case
ax1.legend([line1, line2], ['yep', 'nope'], bbox_to_anchor=[0.5, 0], 
           loc='upper center', ncol=2, borderaxespad=0.25)

plt.show()

enter image description here

27
Joe Kington