TL;DR
matplotlibでax.text()
を用いて描画したテキストのバウンディングボックス(bounding box, bbox)を取得するには次のようにします。
調査した環境はmacOS Big Sur 11.2.3, Python 3.9.2, matplotlib 3.3.4です。
import matplotlib.pyplot as plt
fig, ax = plt.subplots(1,1)
# 図の範囲を指定する(これがないと正しくbboxを取得できない)
ax.set_xlim(0, 1)
ax.set_ylim(0, 1)
# 先に描画を行う(これがないとエラーになる)
fig.canvas.draw()
# テキストの描画
text = ax.text(0.2, 0.2, "abcdefg0123あいう日本語", color='black', fontname="GenEi Gothic P", fontsize=20)
# グラフの座標でのbboxの取得
bbox = text.get_window_extent().transformed(ax.transData.inverted())
# bboxの描画
ax.plot([bbox.x0, bbox.x0, bbox.x1, bbox.x1, bbox.x0], [bbox.y0, bbox.y1, bbox.y1, bbox.y0, bbox.y0])
plt.show()
注意点
先にfig.canvas.draw()
を呼ぶ
fig.canvas.draw()
を呼ばないと次のようなエラーが出ます。
RuntimeError Traceback (most recent call last)
<ipython-input-42-009947e9c4d3> in <module>
12
13 # グラフ内の座標でのbboxの取得
---> 14 bbox = text.get_window_extent().transformed(ax.transData.inverted())
15
16 # bboxの描画
~/miniconda3/envs/cartopy-env/lib/python3.9/site-packages/matplotlib/text.py in get_window_extent(self, renderer, dpi)
897 self._renderer = self.figure._cachedRenderer
898 if self._renderer is None:
--> 899 raise RuntimeError('Cannot get window extent w/o renderer')
900
901 with cbook._setattr_cm(self.figure, dpi=dpi):
RuntimeError: Cannot get window extent w/o renderer
図の範囲を設定する
ax.set_xlim(0, 1)
ax.set_ylim(0, 1)
を書かず、図の範囲を設定しない場合、bboxが正しく取得できません。
.inverse_transformed()
は非推奨
古い情報だと
bbox = text.get_window_extent().transformed(ax.transData.inverted())
の部分を
bbox = text.get_window_extent().inverse_transformed(ax.transData)
と書いていることがありますが、これは非推奨(deprecated)です。
<ipython-input-45-c5bc8ab82cc2>:14: MatplotlibDeprecationWarning:
The inverse_transformed function was deprecated in Matplotlib 3.3 and will be removed two minor releases later. Use transformed(transform.inverted()) instead.
bbox = text.get_window_extent().inverse_transformed(ax.transData)