Is there any way I can specify the bottom right corner coordinates of a text box using matplotlib?
the code for my box is:
plt.text(x_max-2.7e+3, y_min+1e+5, box_text, style='italic',
bbox={'facecolor':'white', 'alpha':0.5, 'pad':10})
and that produces this for the current plot:
however, those coordinate values were found by trial and error, and the ranges and orders of magnitude for my data will be different for different plots as well.. I would like a way that I can specify the coordinates of the bottom right corner of the text box to be (x_max, y_min) and it would automatically draw the box from there.
Is there any way to do this?
Not surprisingly, the answer is yes. However, there is a much simpler way to do what you want. Let me begin with a bit of background first.
plt.text
is just a wrapper that creates a mpl.text.Text
object on the current axes. Unfortunately, Text
anchors itself based on the text alignment properties, and you can't specify an arbitrary point of the text box to anchor. This is unfortunate because there is a whole tutorial on how to position text using the axis transform (coordinate system) instead of the data.
Fortunately, there are some helper classes in matplotlib.offsetbox
that do exactly what you want. These classes are described in the tutorial, and a couple of relevant examples are shown in the sample gallery here and here. The particular class you are looking for is mpl.offsetbox.AnchoredText
. You would set up your text box like this:
from matplotlib.offsetbox import AnchoredText
...
text_box = AnchoredText(box_text, frameon=True, loc=4, pad=0.5)
plt.setp(text_box.patch, facecolor='white', alpha=0.5)
plt.gca().add_artist(text_box)
frameon=True
makes the Patch
behind the text visible. loc=4
lines up the bottom right corner of the box with that of the Axes
. pad
is now in units of fractions of your font size. plt.setp
is a utility function to set multiple properties on an bunch of objects at once. The first argument in this case is just a single patch, but normally you would pass in a list of things to operate on.
Since you have to add an AnchoredText
directly to an Axes
, I would recommend switching to the Object Oriented API. Your code would look very similar, but you would have more direct access to the underlying objects. You would create your figure and axes using something like plt.subplots
. Then you would plot your data using the methods of Axes
that correspond to the usual pyplot methods. Your code would look like this:
from matplotlib import pyplot as plt
from matplotlib.offsetbox import AnchoredText
fig, ax = plt.subplots()
ax.plot(...)
text_box = AnchoredText(box_text, frameon=True, loc=4, pad=0.5)
plt.setp(text_box.patch, facecolor='white', alpha=0.5)
ax.add_artist(text_box)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With