【问题标题】:Matplotlib text bounding box dimensionsMatplotlib 文本边界框尺寸
【发布时间】:2014-08-26 04:48:17
【问题描述】:

我想做什么:

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

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

我尝试过的:

t 成为一个文本实例。

  1. t.get_window_extent(renderer)

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

  2. t._get_bbox_patch():

    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 已实例化,但在渲染时间之前并未实际填充实际尺寸。

那么,我怎样才能在我用于传递的 xy 参数的相同坐标系统单位中获取文本实例边界框的位置和尺寸到ax.text(...)

【问题讨论】:

    标签: python macos matplotlib


    【解决方案1】:

    这可能有点帮助。

    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       ],\n       [ 4.21607125,  2.23034396]])')
    

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

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

    任何 Text 实例都可以在窗口坐标中报告其范围(负 x 坐标在窗口外),但是有一个问题。

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

    所以,在真正绘制图形之前,似乎没有办法查出文字大小。

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

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

    【讨论】:

    • 这对我来说非常有效,唯一的问题是我必须使用 f.canvas.get_renderer() 而不是 f.canvas.renderer
    【解决方案2】:

    有点晚了,但这里有另一个例子,它展示了如何以数据坐标/单位获取文本对象的边界框。它还绘制了围绕文本获得的边界框以进行视觉表示。

    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()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-16
      • 2017-08-20
      • 1970-01-01
      • 1970-01-01
      • 2017-09-30
      • 2011-01-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多