2011-06-06 20 views
6

Matplotlib'de, metin kutusu boyutunu veri koordinatlarına dönüştürmenin bir yolu nedir? Örneğin, bu oyuncak komut dosyasında, metin kutusunun koordinatlarını, bir veri noktasının yanında olacak şekilde ayarlıyorum.Metin boyutunu veri koordinatlarına dönüştürür

#!/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() 

Bunun yerine bu sözde kod gibi bir şey yapmanın bir yolu var mı?

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

cevap

6

Bundan hiç memnun değilim, ama aşağıdaki işler; Benzer bir problem için this code'u bulana kadar hayal kırıklığına uğradım, bu da işleyiciye ulaşmak için bir yol önerdi. Bu gerçek verilere noktası dışına metin kutusu alabilirsiniz iken

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, mutlaka işaretleyici veya hata çubuğunun dışına kutuyu almaz. Bu yüzden pratikte ne kadar yararlı olacağını bilmiyorum, ama sanırım tüm çizilmiş nesnelerin üzerinde dolaşmak ve metni yoluna girene kadar taşımak zor olmaz. Ben bağlantılı kod benzer bir şey çalışır düşünüyorum.

Düzenleme: Lütfen bunun açıkça bir nezaket kabul edildiğini unutmayın; Aslında bunu yapmak istesem Joe Kington'un çözümünü kullanırdım, ve başka herkes de olmalı. : ^)

+0

Vay, bu harika bir şey! Benim özel durumumda, annotate(), Joe'nun belirttiği gibi işi yapar, ama numaranız çok havalıdır. Teşekkürler bir gazillion! –

10

Genel olarak, metnin boyutunu çizilene kadar alamazsınız (böylelikle DSM'nin yanıtındaki hackler).

Yapmak istediğiniz şey için, annotate'u kullanmanız çok daha iyi olur.

E.g. Eğer dikey hizalama, yatay hizalama, vs ayarlamak isteyen konum bu yükseklik var ederek puan ofset belirtebilirsiniz ax.annotate('Your text string', xy=(x, y), xytext=(x-0.1, y-0.4))

Not yanı ve böylece metni ofset

(sadece textcoords='offset points' belirtin) Sadece argüman olarak ekleyin annotate (örneğin horizontalalignment='right' veya eşdeğerli ha='right')

+0

Teşekkürler Joe! Bu gerçekten hile yapar. –

İlgili konular