Python 用极坐标法追踪相位、轴和地球方向的椭圆轨道
我想表示双星双星系统的椭圆轨道。我的目标是这样的: 在这里,我有一个沿轴大小的网格,焦点处有一个比例内的恒星,以及次恒星的轨道。沿轨道的十进制数是轨道相位。底部的箭头是地球的方向,轨道上较厚的部分与具体情况下的观测有关——我不需要它。我想从这个图中改变的是:Python 用极坐标法追踪相位、轴和地球方向的椭圆轨道,python,matplotlib,plot,ellipse,polar-coordinates,Python,Matplotlib,Plot,Ellipse,Polar Coordinates,我想表示双星双星系统的椭圆轨道。我的目标是这样的: 在这里,我有一个沿轴大小的网格,焦点处有一个比例内的恒星,以及次恒星的轨道。沿轨道的十进制数是轨道相位。底部的箭头是地球的方向,轨道上较厚的部分与具体情况下的观测有关——我不需要它。我想从这个图中改变的是: 轨道相位:我想要的不是沿着轨道的数字,而是从焦点到轨道的“虚线射线”,以及它们上面的轨道相位: 我不想让十字架(0,0) 我想重新确定轨道的方向,以便0.0相位位于绘图的左上部分,地球方向是一个向上的直箭头(我的系统参数与此处绘制的参数不
import numpy as np
import matplotlib.pyplot as plt
cos = np.cos
pi = np.pi
a = 10
e = 0.1
theta = np.linspace(0,2*pi, 360)
r = (a*(1-e**2))/(1+e*cos(theta))
fig = plt.figure()
ax = fig.add_subplot(111, polar=True)
ax.set_yticklabels([])
ax.plot(theta,r)
print(np.c_[r,theta])
plt.show()
有件事让你非常接近。绘制一个像样的椭圆不需要极坐标。有一种所谓的
艺术家
你可以随时使用。您可能需要自定义轴标签,如果需要,还可以插入一个或两个箭头:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Ellipse
# initializing the figure:
fig = plt.figure()
# the (carthesian) axis:
ax = fig.add_subplot(111,aspect='equal')
ax.grid(True)
# parameters of the ellipse:
a = 5.0
e = 4.0
b = np.sqrt(a**2.0 - e**2.0)
# the center of the ellipse:
x = 6.0
y = 6.0
# the angle by which the ellipse is rotated:
angle = -45.0
#angle = 0.0
# plotting the ellipse, using an artist:
ax.add_artist(Ellipse(xy=[x,y], width=2.0*a, height=2.0*b, \
angle=angle, facecolor='none'))
ax.set_xlim(0,2.0*x)
ax.set_ylim(0,2.0*y)
# marking the focus (actually, both)
# and accounting for the rotation of the ellipse by angle
xf = [x - e*np.cos(angle * np.pi/180.0),
x + e*np.cos(angle * np.pi/180.0)]
yf = [y - e*np.sin(angle * np.pi/180.0),
y + e*np.sin(angle * np.pi/180.0)]
ax.plot(xf,yf,'xr')
# plotting lines from the focus to the ellipse:
# these should be your "rays"
t = np.arange(np.pi,3.0*np.pi,np.pi/5.0)
p = b**2.0 / a
E = e / a
r = [p/(1-E*np.cos(ti)) for ti in t]
# converting the radius based on the focus
# into x,y coordinates on the ellipse:
xr = [ri*np.cos(ti) for ri,ti in zip(r,t)]
yr = [ri*np.sin(ti) for ri,ti in zip(r,t)]
# accounting for the rotation by anlge:
xrp = [xi*np.cos(angle * np.pi/180.0) - \
yi*np.sin(angle * np.pi/180.0) for xi,yi in zip(xr,yr)]
yrp = [xi*np.sin(angle * np.pi/180.0) + \
yi*np.cos(angle * np.pi/180.0) for xi,yi in zip(xr,yr)]
for q in range(0,len(t)):
ax.plot([xf[0], xf[0]+xrp[q]],[yf[0], yf[0]+yrp[q]],'--b')
# put labels outside the "rays"
offset = 0.75
rLabel = [ri+offset for ri in r]
xrl = [ri*np.cos(ti) for ri,ti in zip(rLabel,t)]
yrl = [ri*np.sin(ti) for ri,ti in zip(rLabel,t)]
xrpl = [xi*np.cos(angle * np.pi/180.0) - \
yi*np.sin(angle * np.pi/180.0) for xi,yi in zip(xrl,yrl)]
yrpl = [xi*np.sin(angle * np.pi/180.0) + \
yi*np.cos(angle * np.pi/180.0) for xi,yi in zip(xrl,yrl)]
# for fancy label rotation reduce the range of the angle t:
tlabel = [(ti -np.pi)*180.0/np.pi for ti in t]
for q in range(0,len(tlabel)):
if tlabel[q] >= 180.0:
tlabel[q] -= 180.0
# convert the angle t from radians into degrees:
tl = [(ti-np.pi)*180.0/np.pi for ti in t]
for q in range(0,len(t)):
rotate_label = angle + tlabel[q]
label_text = '%.1f' % tl[q]
ax.text(xf[0]+xrpl[q],yf[0]+yrpl[q],label_text,\
va='center', ha='center',rotation=rotate_label)
plt.show()
上述示例将导致此图:
说明:
- 可以使用,而不是使用极坐标
- 命名法基于上提供的定义
- 艺术家设置中的角度旋转椭圆。该角度稍后用于旋转光线和标签的坐标(这只是数学)
- 光线是从光线中导出的李>
- 角度
从t
到pi
运行,因为我假设这将符合光线应该从哪里开始的想法。对于3.0*pi
到0
,您将获得相同的光线。我使用而不是2.0*pi
,因为在本例中我需要定义的增量(linspace
,或36度)李>pi/5.0
- 射线末端的标签放置为,变量
控制椭圆和标签之间的距离。根据需要进行调整李>offset
- 为了使标签文本方向与光线对齐,我将角度
减小到t
到0
度。与180
到0
度的全范围相比,这使得可读性更好360
- 为了简单起见,对于标签文本,我只使用了角度,
。用更适合您的目的的信息替换此信息李>t
- 角度
,在放置标签的循环之前从弧度转换为度。在循环内部,t
的每个元素都转换为字符串。这允许更多的格式控制(例如,tl
如果需要3位小数)%.3f
t=np.arange(np.pi,3.0*np.pi,np.pi/5.0)
设置的。尝试将5.0
更改为10.0
,并观察差异。或者我误解了你所说的旋转。不是真的,我的意思是:我想要的是从x=0的直线开始的0.0
角度,而不是现在距离焦点最近的点的角度。@Py ser:我把“x=0的直线”解释为y
-轴。因此,考虑光线在<代码>π-(π/2 +角)< /代码>开始,在光线旋转之后,应该导致它们的正确对齐。或者,找出光线之间是否存在适合您的原因的增量(使光线与y
-轴的方向对齐),然后只需更改标签的顺序。在哪里播放pi-(pi/2.0+角度)
?我应该从这个值开始重新定义t
变量吗?