将文本大小转换为数据坐标

8 投票
2 回答
3258 浏览
提问于 2025-04-16 19:01

在matplotlib中,有什么方法可以把文本框的大小转换成数据坐标呢?

比如,在这个简单的脚本中,我正在调整文本框的坐标,以便它能靠近一个数据点。

#!/usr/bin/python 
import matplotlib.pyplot as plt

xx=[1,2,3]
yy=[2,3,4]
dy=[0.1,0.2,0.05]

fig=plt.figure()
ax=fig.add_subplot(111)

ax.errorbar(xx,yy,dy,fmt='ro-',ms=6,elinewidth=4)

# HERE: can one get the text bbox size?
txt=ax.text(xx[1]-0.1,yy[1]-0.4,r'$S=0$',fontsize=16)

ax.set_xlim([0.,3.4])
ax.set_ylim([0.,4.4])

plt.show()

有没有什么办法可以像这个伪代码那样做呢?

x = xx[1] - text_height
y = yy[1] - text_width/2
ax.text(x,y,text)

2 个回答

11

一般来说,你无法在文本绘制之前获取它的大小(这就是@DSM回答中提到的一些技巧)。

对于你想做的事情,使用annotate会更好。

比如说,你可以这样写:ax.annotate('你的文本内容', xy=(x, y), xytext=(x-0.1, y-0.4))

注意,你也可以用点数来指定偏移量,这样就可以根据文本的高度来调整位置(只需指定textcoords='offset points')。

如果你想调整垂直对齐、水平对齐等,只需将这些作为参数添加到annotate中(例如horizontalalignment='right',或者同样可以写成ha='right')。

7

我对这个结果一点都不满意,但下面的方法确实有效;我之前很沮丧,直到我找到这段代码,它解决了一个类似的问题,并给出了获取渲染器的方法。

import matplotlib.pyplot as plt

xx=[1,2,3]
yy=[2,3,4]
dy=[0.1,0.2,0.05]

fig=plt.figure()
figname = "out.png"
ax=fig.add_subplot(111)

ax.errorbar(xx,yy,dy,fmt='ro-',ms=6,elinewidth=4)

# start of hack to get renderer
fig.savefig(figname)
renderer = plt.gca().get_renderer_cache()
# end of hack

txt = ax.text(xx[1], yy[1],r'$S=0$',fontsize=16)
tbox = txt.get_window_extent(renderer)
dbox = tbox.transformed(ax.transData.inverted())
text_width = dbox.x1-dbox.x0
text_height = dbox.y1-dbox.y0
x = xx[1] - text_height
y = yy[1] - text_width/2
txt.set_position((x,y))

ax.set_xlim([0.,3.4])
ax.set_ylim([0.,4.4])

fig.savefig(figname)

另一方面,虽然这个方法可以把文本框从实际的数据中移开,但它不一定能把文本框移开标记或误差条的位置。所以我不太确定这个方法在实际中有多有用,但我想要把所有绘制的对象都循环一遍,把文本移动到不挡路的地方应该也不难。我觉得链接的代码也尝试了类似的做法。

补充:请注意,这显然是个礼貌的接受;如果我真的想做到这一点,我会使用Joe Kington的解决方案,其他人也应该这样做。 :^)

撰写回答