Andrew Latham
Andrew Latham

Reputation: 6132

MatPlotLib -- size of object

I am trying to draw a figure where I have a text object located at (1, 5) on a grid and I want to draw an arrow pointing down from the bottom-center of the object. Problem is, I don't know where that center coordinate is. The y-coordinate is obviously 5 or so, but the x-coordinate depends on the length of the object.

What I'd like to do is just something like Arrow(1 + obj.x_size / 2, 5, etc.) but I'm having trouble finding a way to actually get the size of the object itself. What should I use?

i.e.

t = ax.text(0.5, 5, r'$x_n = (2.1, 4.4) \in R^2$', fontsize=18)
ax.arrow(???, 5, 0, -2, fc='k', ec='k', head_width=0.5, head_length=1)

Upvotes: 2

Views: 226

Answers (1)

Amy Teegarden
Amy Teegarden

Reputation: 3972

You can use the get_window_extent() method to get the bounding box of the text. This will be in display coordinates, which is not what you want for the arrow. You'll need to use a transform to turn the display coordinates into data coordinates. In order for this to work properly, the axis limits need to be whatever size they're going to be when you're done making the figure. That means that before you get the bounding box, you'll either need to set the x and y axis limits manually or plot everything you're planning to plot. Then, transform the bounding box to data coordinates, get the coordinates of the corners, and use those to make the arrow.

import matplotlib.pyplot as plt
from matplotlib.transforms import TransformedBbox
fig, ax = plt.subplots()
t = ax.text(0.5, 5, r'$x_n = (2.1, 4.4) \in R^2$', fontsize=18)
#draw the plot so it's possible to get the bounding box
plt.draw()

#either plot everything or set the axes to their final size
ax.set_xlim((0, 10))
ax.set_ylim(0, 10)
#get the bbox of the text
bbox = t.get_window_extent()
#get bbox in data coordinates
tbbox = TransformedBbox(bbox, ax.transData.inverted())
coords = tbbox.get_points()
#get center of bbox
x = (coords[1][0] + coords[0][0]) / 2
#get bottom of bbox
y = coords[0][1]
ax.arrow(x, y, 0, -2, fc='k', ec='k', head_width=0.5, head_length=1)

plt.show()

Plot with text and arrow

Upvotes: 2

Related Questions