如何让注释保持在可见窗口内?

3

在Matplotlib中,我怎样才能让注释保持在窗口内?基本上,我想要固定它以便黄色框可见:

enter image description here

这是由此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)

很遗憾,我还没有找到这样的方法。

也许有内置方法可以自动地将注释限制在边界内。但是我也一直没有找到这样的方法。

如何将注释保持在图形窗口的边界内?

1个回答

4

既然你说如果知道注释是否在框架内就可以做到,下面是一种实现方式:

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的示例:

enter image description here enter image description here

还有一个返回false的例子:

enter image description here

让我们详细解释一下这个函数,以便您可以根据它进行工作:
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)

链接:


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接