I want to have some box annotations inside a plot with matplotlib. Is there a way to specify a fixed width for the textbox? I want to be able to have some random text inside my annotation that gets adjusted automatically, not to the sides, but top down.
Here is a minimal example:
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.offsetbox import AnnotationBbox, TextArea
fig, ax = plt.subplots()
t = TextArea("Test 1")
xi, yi = 0.05, 0.1
ab = AnnotationBbox(t, xy=(xi, yi))
ax.add_artist(ab)
t = TextArea("Test 2 blah blah blah")
xi, yi = 0.1, 0.15
ab = AnnotationBbox(t, xy=(xi, yi))
ax.add_artist(ab)
# something along the lines of creating a rectangle of fixed width and having some text inside it
width, height = 0.025, 0.05
xi, yi = 0.2, 0.1
m = matplotlib.patches.Rectangle((xi - width / 2, yi - height / 2), width, height)
ax.add_patch(m)
ax.set_ylim([0, 0.3])
ax.set_xlim([0, 0.3])
This produces the following plot:

As you can see, Test 2 blah blah blah adjusts the surrounding box automatically to the sides, whereas I'd like to specify a certain width, past which the remaining text would be written on the next line. I know matplotlib.offsetbox.AnnotationBbox has some parameters such as xybox, xycoords and boxcoords, but I haven't found any way to set them up so that the annotation behaves like this. I have also looked at the text() function in the pyplot module (or text method of the Axes class) and I haven't found any way to specify a width. Any help is appreciated.
matplotlib has something to auto wrap the text, see this example, or this example.
I don't think you can do it with him AnnotationBbox, but using the plt.text, with the parameter wrap=True:
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
text = "Test 2 blah blah blah"
xi, yi = 0.2, 0.15
txt = ax.text(xi, yi, text, wrap=True)
# Override the object's method for getting available width
# Note width is in pixels.
txt._get_wrap_line_width = lambda : 70.
# the same but with a box
text = "Iggy Pop blah blah blah blah blah blah blah"
txt = ax.text(.5, .6, text, ha='left', va='top', wrap=True,
bbox=dict(boxstyle='square', fc='w', ec='r'))
txt._get_wrap_line_width = lambda : 60.

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