私もこれに苦労しました。重要な点は、実際にテキストを描画するまで、matplotlib がテキストの大きさを決定しないことです。したがって、明示的に を呼び出しplt.draw()
て境界を調整し、再度描画する必要があります。
このメソッドは、ドキュメントget_window_extent
に従って、データ座標ではなく、表示座標で回答を返すことになっています。ただし、キャンバスがまだ描画されていない場合は、 のキーワード引数で指定した座標系で応答するようです。そのため、上記のコードは を使用して動作しますが、 は動作しません。textcoords
annotate
textcoords='data'
'offset points'
次に例を示します。
x = np.linspace(0,360,101)
y = np.sin(np.radians(x))
line, = plt.plot(x, y)
label = plt.annotate('finish', (360,0),
xytext=(12, 0), textcoords='offset points',
ha='left', va='center')
bbox = label.get_window_extent(plt.gcf().canvas.get_renderer())
print(bbox.extents)

array([ 12. , -5. , 42.84375, 5. ])
テキスト ラベルが軸内に収まるように範囲を変更します。指定された値はbbox
あまり役に立ちません: ラベル付きのポイントに相対的なポイントであるため: x で 12 ポイントのオフセット、10 ポイントのフォント (-5 から 5 でイ)。そこから新しい一連の軸境界に到達する方法を理解することは自明ではありません。
ただし、メソッドを描画した後で再度メソッドを呼び出すと、まったく異なる bbox が得られます。
bbox = label.get_window_extent(plt.gcf().canvas.get_renderer())
print(bbox.extents)
今、私たちは得る
array([ 578.36666667, 216.66666667, 609.21041667, 226.66666667])
これは表示座標であり、慣れ親しんだ方法で変換できax.transData
ます。したがって、ラベルを境界に入れるには、次のようにします。
x = np.linspace(0,360,101)
y = np.sin(np.radians(x))
line, = plt.plot(x, y)
label = plt.annotate('finish', (360,0),
xytext=(8, 0), textcoords='offset points',
ha='left', va='center')
plt.draw()
bbox = label.get_window_extent()
ax = plt.gca()
bbox_data = bbox.transformed(ax.transData.inverted())
ax.update_datalim(bbox_data.corners())
ax.autoscale_view()

プロットが一度描画された後は、plt.gcf().canvas.get_renderer()
明示的に渡す必要がなくなったことに注意してください。get_window_extent
また、自動スケーリングが自動的にラウンド数までノッチできるように、update_datalim
代わりにxlim
and をylim
直接使用しています。
この回答をノート形式でここに投稿しました。