如何在Matplotlib窗口中保留注释?基本上,我想解决这个问题,以便黄色框可见:
这是由这个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()
我打算将注释作为鼠标悬停,但是没有必要实现该代码来显示问题(我已经想出了如何做到这一点)。但是,也许有一种方法可以使用tkinter为它添加工具提示,这可能会完全解决我的问题。
也许有办法检测注释是否在窗口之外。如果有这样的方式,这个伪代码会做我想要的:
if annotation.is_not_within(window):
draw_annotation_to_go_the_other_way(annotation)
不幸的是,我找不到这样的方式。
此外,也许有一种内置方法可以自动将注释保留在边界内。我也一直无法找到这样的方式。
如何将注释保留在图形窗口的范围内?
答案 0 :(得分:3)
既然你知道如果你知道注释是否在框架内,你可以这样做,这是一种方法:
def in_frame(annotation):
pyplot.show(block=False) # we need this to get good data on the next line
bbox = annotation.get_bbox_patch()
uleft_coord = (0, bbox.get_height())
pnt = bbox.get_data_transform().transform_point(uleft_coord)
return pyplot.gcf().get_window_extent().contains(*pnt)
我们的想法是,我们从注释的bbox(边界框)中获取一个点,并询问图形(框架)的bbox是否包含该点。这只检查左上角的点,但我们可以通过检查更多的角来改善。对于您的图片,这会返回False
。以下是一些返回true的示例:
另一个返回false:
让我们更详细地解释一下这个功能,这样你就可以解决它了:
pyplot.show(block=False) # display the figure, so that the annotation bbox
# will return the actual box. Otherwise it says the
# bbox has 1 pixel width and height.
bbox = annotation.get_bbox_patch()
uleft_coord = (0, bbox.get_height())
# kind of scary, so let's break this down:
pnt = bbox.get_data_transform().transform_point(uleft_coord)
bbox.get_data_transform() # this gives us a transform that can
# convert a pixel from the coordinates
# of the bbox to coordinates that the
# figure uses.
pnt = (...).transform_point(uleft_coord) # this converts the uleft_coord into
# the coordinate system of the figure
# This is that all together:
pnt = bbox.get_data_transform().transform_point(uleft_coord)
# here's another of those scary lines:
return pyplot.gcf().get_window_extent().contains(*pnt)
pyplot.gcf() # this calls "get current figure"
pyplot.gcf().get_window_extent() # and now let's get its bbox
( ... ).contains(*pnt) # and ask it if it contains pnt
return pyplot.gcf().get_window_extent().contains(*pnt)
链接: