Matplotlib text bounding box dimensions

What I want to do:

I want to get the position and size of a text instance in matplotlib world units (not in screen pixels) in order to calculate and prevent text overlays.

I work on Mac OSX 10.9.3, Python 2.7.5, matplotlib 1.3.1.

What I tried:

Let t be a text instance.

  1. t.get_window_extent (visualization tool) :

    This gets the bounding rectangle dimensions in pixels, and I need world coordinates (normalized between -1.0 and 1.0 in my case).

  2. t._get_bbox_patch ():

    t = ax.text(x, y, text_string, prop_dict, bbox=dict(facecolor='red', alpha=0.5, boxstyle='square')) print t._get_bbox_patch() 

    When I execute the above sequence, the output is FancyBboxPatchFancyBboxPatch(0,0;1x1) . In the image that I am creating, the text instance is displayed correctly with a red border, so the output makes me think that the FancyBbox instance was created, but is not really filled with real measurements until the rendering time.

So, how can I get the position and size of the bounding rectangle text instance in the same coordinate system units that I used for the x and y parameters that I passed to ax.text(...) ?

+6
source share
2 answers

This might help a bit.

 import matplotlib.pyplot as plt f = plt.figure() ax = f.add_subplot(111) ax.plot([0,10], [4,0]) t = ax.text(3.2, 2.1, "testing...") # get the inverse of the transformation from data coordinates to pixels transf = ax.transData.inverted() bb = t.get_window_extent(renderer = f.canvas.renderer) bb_datacoords = bb.transformed(transf) # Bbox('array([[ 3.2 , 2.1 ],\n [ 4.21607125, 2.23034396]])') 

This should give what you want. If you want to have coordinates along the coordinates of the figure (0..1.0..1), use the inverse of ax.transAxes .

However, there is a little trick in this decision. Excerpt from matplotlib documentation:

Any instance of Text can report its degree in the coordinates of the window (the negative x coordinate is located outside the window), but there is a rub.

The instance of RendererBase, which is used to calculate the size of the text, is still unknown until the picture is drawn (draw ()). After the window is drawn and the text instance knows its renderer, you can call get_window_extent ().

So, before the picture is actually drawn, it seems that there is no way to know the size of the text.

By the way, you may have noticed that instances of Bbox have an overlaps method that can be used to determine if Bbox overlapping with another ( bb1.overlaps(bb2) ). This may be useful in some cases, but it does not answer the question of how much.

If you have rotated texts, it will be difficult for you to see if they overlap, but you probably already know.

+8
source

A bit late, but here is another example that shows how to get the bounding box of a text object in coordinates / data units. He also draws a bounding rectangle drawn around the text for visual presentation.

 import matplotlib.pyplot as plt # some example plot plt.plot([1,2,3], [2,3,4]) t = plt.text(1.1, 3.1, "my text", fontsize=18) # to get the text bounding box # we need to draw the plot plt.gcf().canvas.draw() # get bounding box of the text # in the units of the data bbox = t.get_window_extent()\ .inverse_transformed(plt.gca().transData) print(bbox) # prints: Bbox(x0=1.1, y0=3.0702380952380954, x1=1.5296875, y1=3.2130952380952382) # plot the bounding box around the text plt.plot([bbox.x0, bbox.x0, bbox.x1, bbox.x1, bbox.x0], [bbox.y0, bbox.y1, bbox.y1, bbox.y0, bbox.y0]) plt.show() 

enter image description here

0
source

All Articles