Matplotlib文本边界框尺寸
我想做的事情:
我想获取在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():
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 参数所用的相同坐标系单位中,获取文本实例的边界框的位置和尺寸呢?
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()
这可能会对你有点帮助。
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之间),那么可以使用ax.transAxes
的反转。
不过,这个解决方案有一个小问题。以下是matplotlib
文档中的一段摘录:
任何文本实例都可以报告它在窗口坐标中的范围(负的x坐标表示在窗口外),但这里有个问题。
用于计算文本大小的RendererBase实例,直到图形被绘制出来(draw())之前是无法知道的。等窗口绘制完成后,文本实例才知道它的渲染器,这时你可以调用get_window_extent()。
所以,在图形真正绘制之前,似乎没有办法知道文本的大小。
顺便提一下,你可能注意到Bbox
实例有一个overlaps
方法,可以用来判断一个Bbox
是否与另一个重叠(bb1.overlaps(bb2)
)。这在某些情况下可能有用,但它并不能回答“重叠多少”的问题。
如果你有旋转的文本,你会很难判断它们是否重叠,不过你可能已经知道这一点。