LoginSignup
0
0

More than 3 years have passed since last update.

matplotlibで描画したテキストのバウンディングボックスを取得する

Posted at

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() 

bbox.png

注意点

先に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が正しく取得できません。
bbox2.png

.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)

参考にしたページ

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0