Search code examples
pythonmatplotlib

Find corner of annotation with background


I am trying to find the corners of the box produced by adding a matplotlib annotation with background color. This is what I have tried:

a = ax.annotate(
  label,
  xy=(x, y),
  backgroundcolor=(0.69, 0.6, 0.65, 0.65),
  color="#444444",
  fontsize=14,
  xytext=(0, 0),
  textcoords="offset pixels",
)

# draw figure to be able to find actual corners
ax.get_figure().canvas.draw()
points = a.get_window_extent().get_points()  # ...or get_tightbbox(), doesn't really matter here
corner_ur = points[1]  # upper right
corner_lr = [points[1][0], points[0][1]]  # lower right
... and so on

However, the bbox returned by a.get_tightbbox() is the bbox of the text, not the whole padded area with background fill. How can I find the corners of the whole padded box?

This image shows in green the result of plotting corner_ur and corner_lr:

An annotation with bg color, and two dots well inside the colored area

The points I get are at the corners of the text's bbox, but not of the whole filled area. How do I get those? (Or, alternatively, how do I find the padding used, to calculate them?)


Solution

  • Turns out Matplotlib annotations use something called a FancyBboxPatch for padding, background color, etc. It can be accessed through Annotation.get_bbox_patch(). In this example we will get what we want from:

    points = a.get_bbox_patch().get_window_extent()
    corner_ur = (points.x1, points.y1)
    corner_lr = (points.x1, points.y0)
    

    (Remember to draw the figure before, so that .get_window_extent() can return something meaningful.)