How can I keep an annotation within the window, in Matplotlib? Basically, I want to fix this so that the yellow box will be visible:
Which was generated by this mcve:
from matplotlib import pyplot
point = pyplot.scatter(0, 0)
s = '''This is some really long text to go into the annotation that is way
too long to fit inside the figure window.'''
annotation = pyplot.annotate(
s=s, xy=(0, 0), xytext=(-10, 10), textcoords='offset points',
ha='right', va='bottom', bbox=dict(boxstyle='round,pad=0.5', fc='yellow')
)
pyplot.show()
I intend for the annotation to be a mouseover, but it's not necessary to implement that code to show the problem (I already figured out how to do that). However, perhaps there is a way to add a tooltip to it using tkinter, and that would probably completely fix my problem.
Perhaps there is a way to detect that the annotation is outside of the window. If there was such a way, this psuedocode would do what I want:
if annotation.is_not_within(window):
draw_annotation_to_go_the_other_way(annotation)
Unfortunately, I haven't been able to find such a way.
Also, perhaps there is a built-in method that keeps the annotation within the bounds automagically. I also have been unable to find such a way.
How can I keep the annotation within the bounds of the figure window?
Since you said you could do it if you knew if the annotation was within the frame, here's a way to do so:
The idea is that we grab a point from the bbox (bounding box) of the annotation, and ask the bbox of the figure (frame) if it contains that point. This only checks the upper-left-hand point, but we could get better by checking more corners. For your image, this returns
False
. Here are some examples that return true:And another that returns false:
Let's explain the function in more detail so you can work off of it:
Links:
annotation.get_bbox_patch()
which returns thisbbox.get_data_transform()
pyplot.gcf()
figure.get_window_extent()
contains(*pnt)