Is it possible to display text in a box through Matplotlib, with automatic line breaks? By using pyplot.text()
, I was only able to print multi-line text that flows beyond the boundaries of the window, which is annoying. The size of the lines is not known in advance… Any idea would be much appreciated!
相关问题
- how to define constructor for Python's new Nam
- streaming md5sum of contents of a large remote tar
- How to get the background from multiple images by
- Carriage Return (ASCII chr 13) is missing from tex
- Evil ctypes hack in python
By setting
wrap = True
when creating the text box, as in the below example. This may have the desired effect.Its been roughly five years but there still doesn't seem to be a great way to do this. Here is my version of the accepted solution. My goal was to allow pixel-perfect wrapping to be selectively applied to individual text instances. I have also created a simple textBox() function which will convert any axes into a text box with custom margins and alignment.
Instead of assuming a particular font aspect ratio or average width, I actually draw the string one word at a time and insert newlines once the threshold is hit. This is horrendously slow compared to the approximations, but still feels quite snappy for strings of <200 words.
Usage:
I dropped a few features which weren't as important to me. Resizing will fail as each call to _wrap() inserts additional newlines into the string but has no way of removing them. This can be solved by either stripping out all \n characters in the _wrap function, or storing the original string somewhere and "resetting" the text instance between wraps.
The contents of this answer were merged into mpl master in https://github.com/matplotlib/matplotlib/pull/4342 and will be in the next feature release.
Wow... This is a thorny problem... (And it exposes a lot of limitations in matplotlib's text rendering...)
This should (i.m.o.) be something that matplotlib has built-in, but it doesn't. There have been a few threads about it on the mailing list, but no solution that I could find to automatic text wrapping.
So, first off, there's no way to determine the size (in pixels) of the rendered text string before it's drawn in matplotlib. This isn't too large of a problem, as we can just draw it, get the size, and then redraw the wrapped text. (It's expensive, but not too excessively bad)
The next problem is that characters don't have a fixed width in pixels, so wrapping a text string to a given number of characters won't necessarily reflect a given width when rendered. This isn't a huge problem, though.
Beyond that, we can't just do this once... Otherwise, it will be wrapped correctly when drawn the first time (on the screen, for example), but not if drawn again (when the figure is resized or saved as an image with a different DPI than the screen). This isn't a huge problem, as we can just connect a callback function to the matplotlib draw event.
At any rate this solution is imperfect, but it should work in most situations. I don't try to account for tex-rendered strings, any stretched fonts, or fonts with an unusual aspect ratio. However, it should now properly handle rotated text.
However, It should attempt automatically wrap any text objects in multiple subplots in whichever figures you connect the
on_draw
callback to... It will be imperfect in many cases, but it does a decent job.