[英]Matplotlib, adding text with more than one line. Adding text that can follow the curve
我已經將文本添加到繪圖中,在每行中編碼,然后調整它看起來像樣,增加或減少寬度,或更改位置。 但是,有沒有辦法讓Python知道你想要文本的位置以及你想要它的設置方式? 然后我可以添加文本,Python將計算出細節。
例如,看看下面的圖片:
在圖中,我在左上角有3行文字,在圖的線上有一行。
我不得不調整3條線以獲得合適的間距。 這不是一項艱巨的任務,但如果我能說這里是文本,這里就是位置,那將很容易,然后Python以適當的間距堆疊它。
對於單獨的線路,我必須進行調整,以便它不在線上並降低線路。 對於這種情況,有可能告訴python我想在情節上方的文字和80%下線?
我習慣了LaTeX
,我可以在沒有硬編碼坐標的情況下進行調整。 優點是
(1) if I want to change the location, I can change the percentage shift and not the coordinate.
(2) if the line is angled, the text will adjust to the line.
(2)的優點是我試圖在圖的頂部放置文字,該文字的頂部向上傾斜。
可以這樣做,還是我要求多少? 如果是這樣,我該怎么做?
以下是實現該圖的代碼:
import numpy as np
import pylab
r1 = 1 # AU Earth
r2 = 1.524 # AU Mars
deltanu = 75 * np.pi / 180 # angle in radians
mu = 38.86984154054163
c = np.sqrt(r1 ** 2 + r2 ** 2 - 2 * r1 * r2 * np.cos(deltanu))
s = (r1 + r2 + c) / 2
am = s / 2
def g(a):
alphag = 2* np.pi - 2 * np.arcsin(np.sqrt(s / (2 * a)))
return (np.sqrt(a ** 3 / mu)
* (alphag - betag - (np.sin(alphag) - np.sin(betag))))
def f(a):
alpha = 2 * np.arcsin(np.sqrt(s / (2 * a)))
beta = 2 * np.arcsin(np.sqrt((s - c) / (2 * a)))
return (np.sqrt(a **3 / mu) * (alpha - betag - (np.sin(alpha)
- np.sin(betag))))
betag = -2 * np.arcsin(np.sqrt((s - c) / (2 * a)))
a = np.linspace(am, 2, 500000)
a = np.linspace(am, 2, 500000)
fig = pylab.figure()
ax = fig.add_subplot(111)
ax.plot(a, f(a), color = '#000000')
ax.plot(a, g(a), color = '#000000')
pylab.xlim((0.9, 2))
pylab.ylim((0, 2))
pylab.xlabel('Semi-major Axis $a$ in AU')
pylab.ylabel('Time of Flight in Years')
pylab.text(1, 1.8, '$r_1 = 1.0$ AU', fontsize = 11, color = 'r')
pylab.text(1, 1.7, '$r_2 = 1.524$ AU', fontsize = 11, color = 'r')
pylab.text(1, 1.6, '$\\Delta \\nu = 75^{\\circ}$', fontsize = 11,
color = 'r')
pylab.text(1.75, 0.35, '$\\alpha = \\alpha_0$', fontsize = 11,
color = 'r')
pylab.savefig('lamberttransferties.eps', format = 'eps')
pylab.show()
您可以使用行分隔符\\n
:
pylab.text(1, 1.5, '$r_1 = 1.0$ AU\n' +\
'$r_2 = 1.524$ AU\n' +\
'$\\Delta \\nu = 75^{\\circ}$', fontsize = 11, color = 'r')
pylab.text()
默認使用數據坐標,但您可以使用相對位置(0,0)
到左下角和(1,1)
到右上角,傳遞參數transform
。 看這個例子:
pylab.text(0.6, 0.75, 'using axis coords', transform=ax.transAxes)
參數: verticalalignment
和horizontalalignment
也可以幫助你。 假設您想要在角落放置文本:
pylab.text(1.,1.,'top-right', transform=ax.transAxes,
horizontalalignment='right', verticalalignment='top')
pylab.text(0.,0.,'bottom-left', transform=ax.transAxes,
horizontalalignment='left', verticalalignment='bottom')
要根據您的數據自動計算文本角度,您可以執行以下方法:
ax.get_data_ratio()
OBS更正指示:如果使用ax.axis('scaled')
則不需要,例如 該算法可以實現如下:
def rtext(line,x,y,s, **kwargs):
from scipy.optimize import curve_fit
xdata,ydata = line.get_data()
dist = np.sqrt((x-xdata)**2 + (y-ydata)**2)
dmin = dist.min()
TOL_to_avoid_rotation = 0.3
if dmin > TOL_to_avoid_rotation:
r = 0.
else:
index = dist.argmin()
xs = xdata[ [index-2,index-1,index,index+1,index+2] ]
ys = ydata[ [index-2,index-1,index,index+1,index+2] ]
def f(x,a0,a1,a2,a3):
return a0 + a1*x + a2*x**2 + a3*x**3
popt, pcov = curve_fit(f, xs, ys, p0=(1,1,1,1))
a0,a1,a2,a3 = popt
ax = pylab.gca()
derivative = (a1 + 2*a2*x + 3*a3*x**2)
derivative /= ax.get_data_ratio()
r = np.arctan( derivative )
return pylab.text(x, y, s, rotation=np.rad2deg(r), **kwargs)
以下測試示例顯示了如何使用它:
ax = pylab.subplot(111)
thetas = np.linspace(0,6*np.pi,1000)
i = np.arange(len(thetas))
xdata = (1. + (3.-1.)*i/len(thetas))*np.cos(thetas)
ydata = (1. + (3.-1.)*i/len(thetas))*np.sin(thetas)
ax.plot(xdata, ydata, color = 'b')
pylab.xlabel('x')
pylab.ylabel('y')
for x, y in zip(xdata,ydata)[::25]:
rtext(ax.lines[0], x, y,
'$\\alpha = \\alpha_0$', fontsize = 14, color = 'r',
horizontalalignment='center', verticalalignment='center')
改變verticalalignment='bottom'
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.