Python 太阳系行星轨道可视化 - 带交互式点击功能
import numpy as np
import matplotlib.pyplot as plt
# 行星参数(轨道半长轴、偏心率、轨道倾角)
planet_params = {
'Mercury': [0.387, 0.205, 7.0],
'Venus': [0.723, 0.007, 3.4],
'Earth': [1.0, 0.017, 0.0],
'Mars': [1.524, 0.093, 1.9],
'Jupiter': [5.203, 0.048, 1.3],
'Saturn': [9.537, 0.056, 2.5],
'Uranus': [19.191, 0.046, 0.8],
'Neptune': [30.069, 0.010, 1.8]
}
# 计算行星的轨道位置
def calculate_orbit(semi_major_axis, eccentricity, inclination):
theta = np.linspace(0, 2*np.pi, 1000)
r = semi_major_axis * (1 - eccentricity**2) / (1 + eccentricity * np.cos(theta))
x = r * np.cos(theta)
y = r * np.sin(theta) * np.cos(np.radians(inclination))
z = r * np.sin(theta) * np.sin(np.radians(inclination))
return x, y, z
# 绘制太阳系行星运行轨道
def plot_orbits():
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
for planet, params in planet_params.items():
x, y, z = calculate_orbit(*params)
ax.plot(x, y, z, label=planet)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
ax.legend()
plt.show()
# 点击行星时弹出新窗口显示行星和其卫星的轨道运行
def on_click(event):
if event.artist.get_label() in planet_params:
fig, ax = plt.subplots()
ax.set_aspect('equal')
ax.set_xlim(-1, 1)
ax.set_ylim(-1, 1)
ax.set_title(event.artist.get_label())
# 在这里添加代码计算和绘制行星及其卫星的轨道运行
planet = event.artist.get_label()
params = planet_params[planet]
x, y, z = calculate_orbit(*params)
ax.plot(x, y)
plt.show()
# 绘制太阳系行星运行轨道
plot_orbits()
# 为每个行星添加点击事件
fig = plt.gcf()
for planet, params in planet_params.items():
for line in fig.axes[0].lines:
if line.get_label() == planet:
line.set_picker(5)
break
fig.canvas.mpl_connect('pick_event', on_click)
在获取行星轨道线的循环中,使用了错误的索引,导致出现了'list index out of range'错误。正确的做法是在外层循环中使用ax.lines
来获取所有的轨道线。
修改后的代码如下:
# 点击行星时弹出新窗口显示行星和其卫星的轨道运行
def on_click(event):
if event.artist.get_label() in planet_params:
fig, ax = plt.subplots()
ax.set_aspect('equal')
ax.set_xlim(-1, 1)
ax.set_ylim(-1, 1)
ax.set_title(event.artist.get_label())
# 在这里添加代码计算和绘制行星及其卫星的轨道运行
planet = event.artist.get_label()
params = planet_params[planet]
x, y, z = calculate_orbit(*params)
ax.plot(x, y)
plt.show()
# 绘制太阳系行星运行轨道
plot_orbits()
# 为每个行星添加点击事件
fig = plt.gcf()
for planet, params in planet_params.items():
for line in fig.axes[0].lines:
if line.get_label() == planet:
line.set_picker(5)
break
fig.canvas.mpl_connect('pick_event', on_click)
运行修改后的代码,即可正常绘制行星及其卫星的轨道运行。
原文地址: http://www.cveoy.top/t/topic/o22w 著作权归作者所有。请勿转载和采集!