#python #matplotlib
#python #matplotlib
Вопрос:
Каков способ преобразования размера текстового поля в координаты данных в 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)
Ответ №1:
Вообще говоря, вы не можете получить размер текста до тех пор, пока он не будет отрисован (отсюда и хаки в ответе @DSM).
Для того, что вы хотите сделать, вам было бы намного лучше использовать annotate .
Например. ax.annotate('Your text string', xy=(x, y), xytext=(x-0.1, y-0.4))
Обратите внимание, что вы также можете указать смещение в точках и, таким образом, сместить текст на его высоту (просто укажите textcoords='offset points'
)
Если вы хотите настроить выравнивание по вертикали, горизонтали и т.д., Просто добавьте их в качестве аргументов в annotate
(например, horizontalalignment='right'
или эквивалентно ha='right'
)
Ответ №2:
Я совсем не доволен этим, но следующее работает; я был разочарован, пока не нашел этот код для аналогичной проблемы, который подсказал способ добраться до средства визуализации.
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)
OTOH, хотя это может вывести текстовое поле из точки фактических данных, это не обязательно уберет поле с пути маркера или строки ошибок. Так что я не знаю, насколько это будет полезно на практике, но я думаю, что было бы не так сложно перебирать все нарисованные объекты и перемещать текст, пока он не исчезнет с дороги. Я думаю, что связанный код пытается сделать что-то подобное.
Редактировать: Пожалуйста, обратите внимание, что это было явно принято из вежливости; я бы использовал решение Джо Кингтона, если бы я действительно хотел это сделать, и так должны все остальные. : ^)
Комментарии:
1. Вау, это круто! В моем конкретном случае annotate () выполняет свою работу, как указал Джо, но ваш трюк просто такой классный. Огромное спасибо!