我想代表两颗恒星二元系统的椭圆轨道。我的目标是这样的:
我有一个沿轴的大小网格,焦点上的一个星形星,以及二级星的轨道。沿轨道的十进制数是轨道相位。底部的箭头是地球方向,轨道上的厚部分与特定情况的观察有关 - 我不需要它。我想从这个阴谋中改变的是:
轨道阶段:我不想沿轨道上的数字,而是想从焦点到轨道的“虚线”,以及它们上方的轨道相位:
我不希望交叉(0,0);
我想重新定位轨道,以便0.0阶段位于绘图的左上角部分,地球方向是向上指向的直箭头(我的系统参数不同从这里绘制的那个)。
我试图寻找python示例,但我唯一提出的(from here)是极地情节:
这并不是我想要的真正代表,但仍然是一个开始:
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()
答案 0 :(得分:3)
这是让你非常接近的东西。您不需要极坐标来绘制一个合适的椭圆。有一个你可以轻易利用的所谓artist
您可能必须自定义轴标签,如果需要,可以插入一两个箭头:
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()
上面的例子将导致这个数字:
解释:
artist
to plot the ellipse,而不是使用极坐标angle
会旋转椭圆。此角度稍后用于旋转光线和标签的坐标(这是只是数学)t
从pi
到3.0*pi
,因为我认为这与您对射线应该从哪里开始的想法相对应。您获得0
到2.0*pi
的相同光线。我使用np.arange
而不是linspace
,因为我希望在此示例中定义增量(pi/5.0
或36度)。 text
,变量offset
控制椭圆与标签之间的距离。根据需要调整。 t
缩小到范围0
到180
度。与0
到360
度的全部范围相比,这提高了可读性。t
,以简化。用适合您目的的任何信息替换它。 t
在放置标签的循环之前从弧度转换为度数。在循环内部,tl
的每个元素都转换为字符串。这允许更多的格式控制(例如%.3f
,如果您需要3位小数)