关于python:Matplotlib文本边界框尺寸

Matplotlib text bounding box dimensions

我想做的事:

我想以matplotlib世界单位(而不是屏幕像素)获取文本实例的位置和尺寸,目的是计算和防止文本重叠。

我正在Mac OSX 10.9.3,Python 2.7.5,matplotlib 1.3.1上进行开发。

我尝试过的

令t为文本实例。

  • t.get_window_extent(renderer):

    这将获得边框尺寸(以像素为单位),并且我需要世界坐标(在我的情况下标准化为-1.0和1.0之间)。

  • t._get_bbox_patch():

    1
    2
    t = ax.text(x, y, text_string, prop_dict, bbox=dict(facecolor='red', alpha=0.5, boxstyle='square'))
    print t._get_bbox_patch()

    当我执行以上序列时,输出为FancyBboxPatchFancyBboxPatch(0,0;1x1)。在我生成的图像中,文本实例使用红色边框正确渲染,因此输出使我认为FancyBbox已实例化,但直到渲染时才实际填充实际尺寸。

  • 因此,如何在传递给ax.text(...)的x和y参数所用的同一个坐标系单位中,获取文本实例边界框的位置和尺寸?


    这可能会有所帮助。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    import matplotlib.pyplot as plt

    f = plt.figure()
    ax = f.add_subplot(111)
    ax.plot([0,10], [4,0])
    t = ax.text(3.2, 2.1,"testing...")

    # get the inverse of the transformation from data coordinates to pixels
    transf = ax.transData.inverted()
    bb = t.get_window_extent(renderer = f.canvas.renderer)
    bb_datacoords = bb.transformed(transf)

    # Bbox('array([[ 3.2       ,  2.1       ],
           [ 4.21607125,  2.23034396]])')

    这应该给你想要的。如果要使用图形坐标(0..1,0..1)表示坐标,请使用ax.transAxes的倒数。

    但是,此解决方案有一个小问题。 matplotlib文档的摘录:

    任何Text实例都可以在窗口坐标中报告其范围(负x坐标在窗口外部),但是存在摩擦。

    在绘制图形之前(draw()),用于计算文本大小的RendererBase实例是未知的。在绘制窗口并且文本实例知道其渲染器之后,可以调用get_window_extent()。

    因此,在真正绘制图形之前,似乎没有办法找出文本大小。

    顺便说一句,您可能已经注意到Bbox实例具有方法overlaps,该方法可以用于查找Bbox是否与另一个对象(bb1.overlaps(bb2))重叠。在某些情况下这可能很有用,但不能回答"多少"这个问题。

    如果您旋转了文本,将很难查看它们是否重叠,但是您可能已经知道了。


    稍晚一点,但是这里是另一个示例,它显示了如何以数据坐标/单位获取文本对象的边界框。它还为文本的视觉表示绘制了在文本周围获得的边界框。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    import matplotlib.pyplot as plt

    # some example plot
    plt.plot([1,2,3], [2,3,4])

    t = plt.text(1.1, 3.1,"my text", fontsize=18)

    # to get the text bounding box
    # we need to draw the plot
    plt.gcf().canvas.draw()


    # get bounding box of the text
    # in the units of the data
    bbox = t.get_window_extent()\
        .inverse_transformed(plt.gca().transData)


    print(bbox)
    # prints: Bbox(x0=1.1, y0=3.0702380952380954, x1=1.5296875, y1=3.2130952380952382)


    # plot the bounding box around the text
    plt.plot([bbox.x0, bbox.x0, bbox.x1, bbox.x1, bbox.x0],
             [bbox.y0, bbox.y1, bbox.y1, bbox.y0, bbox.y0])

    plt.show()

    enter image description here