Hello, I have a code that computes a trajectory of a body around the Earth when the only force acting on it is the gravitation. I’d like to animate the trajectory using Plotly, but I don’t know how.
I’ll show my plot and then the code.
Importing the required libraries
import pandas as pd
import numpy as np
from math import pi
import matplotlib as mpl
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import math
import ipywidgets as widgets
import chart_studio.plotly as py
import cufflinks as cf
import seaborn as sns
import plotly.express as px
import plotly.graph_objects as go
%matplotlib inline
from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot
init_notebook_mode(connected=True)
# Use Plotly locally
cf.go_offline()
Input of Values
#widgets.VBox([TINTE,a,e,i,OM,w,f])
accordion = widgets.Accordion(children=[widgets.FloatText(value=1,disabled=False),
widgets.FloatText(value=7149,disabled=False),
widgets.FloatText(value=0,disabled=False),
widgets.FloatText(value=98,disabled=False),
widgets.FloatText(value=110,disabled=False),
widgets.FloatText(value=100,disabled=False),
widgets.FloatText(value=50,disabled=False)])
accordion.set_title(0, 'Tempo de integração em dias')
accordion.set_title(1, 'Semieixo Maior em km')
accordion.set_title(2, 'Excentricidade')
accordion.set_title(3, 'Inclinação em graus')
accordion.set_title(4, 'Longitude do Nodo em graus')
accordion.set_title(5, 'Argumento do perigeu em graus')
accordion.set_title(6, 'Anomalia Verdadeira Inicial em graus')
display(accordion)
TINTE = accordion.children[0].value
a = accordion.children[1].value
e = accordion.children[2].value
i = accordion.children[3].value
OM = accordion.children[4].value
w = accordion.children[5].value
f = accordion.children[6].value
Mass of central body
Mc = 5.97240e+24 #kg (Terra = 7.97240D+24 Sol = 1.98850D+30)
M2 = 5.97240e+24 #kg (Terra = 7.97240D+24 Sol = 1.98850D+30)
M3 = 7.34600e+22 #kg Massa da Lua
G = 6.67408e-20 #Valor preparado para km
TN = 27.321660 #Conversor de tempo
System data for entering outgoing data
tempo = list() #time
xc = list()
yc = list()
zc = list()
Transformation of orbital elements in position and velocity in the ECI coordinate system
P = a*(1-e**2)
R = P/(1+e*(np.cos(np.deg2rad(f))))
X = list()
X.append(R*((np.cos(np.deg2rad(OM)))*(np.cos(np.deg2rad(w+f))) -
(np.sin(np.deg2rad(OM)))*(np.cos(np.deg2rad(i)))*(np.sin(np.deg2rad(w+f)))))
X.append(R*((np.sin(np.deg2rad(OM)))*(np.cos(np.deg2rad(w+f))) +
(np.cos(np.deg2rad(OM)))*(np.cos(np.deg2rad(i)))*(np.sin(np.deg2rad(w+f)))))
X.append(R*(np.sin(np.deg2rad(i)))*(np.sin(np.deg2rad(w+f))))
V = list()
V.append((-((G*Mc)/P)**0.5)*((np.cos(np.deg2rad(OM)))*((np.sin(np.deg2rad(w+f)))+ e*(np.sin(np.deg2rad(w)))) +
(np.sin(np.deg2rad(OM)))*(np.cos(np.deg2rad(i)))*((np.cos(np.deg2rad(w+f))) +
e*(np.cos(np.deg2rad(w))))))
V.append((-((G*Mc)/P)**0.5)*((np.sin(np.deg2rad(OM)))*((np.sin(np.deg2rad(w+f)))+
e*(np.sin(np.deg2rad(w)))) -
(np.cos(np.deg2rad(OM)))*(np.cos(np.deg2rad(i)))*((np.cos(np.deg2rad(w+f))) +
e*(np.cos(np.deg2rad(w))))))
V.append((((G*Mc)/P)**0.5)*((np.sin(np.deg2rad(i)))*(np.cos(np.deg2rad(w+f)))+e*(np.cos(np.deg2rad(w)))))
Vp = (V[0]**2 + V[1]**2 + V[2]**2)**0.5
xc.append(X[0])
yc.append(X[1])
zc.append(X[2])
tempo.append(0)
Vx = V[0]
Vy = V[1]
Vz = V[2]
Runge-Kutah
def RUNGE_KUTAH_4(X,V):
#variáveis
RT = 6370 #km
G = 6.67408e-20 #Valor preparado para km
# estado inicial
t = 0
r = np.array([X[0],X[1],X[2]])
u = np.array([V[0],V[1],V[2]])
#passo
delta_t = 1
def rk4(r,u):
R3 = (r.dot(r))**1.5
m1 = u
k1 = -((G*Mc)/(R3))*r
m2 = u + 0.5*delta_t*k1
#t_2 = t + 0.5*delta_t
r_2 = r + 0.5*delta_t*m1
R3_2 = (r_2.dot(r_2))**1.5
#u_2 = m2
k2 = -((G*Mc)/(R3_2))*r_2
m3 = u + 0.5*delta_t*k2
#t_3 = t + 0.5*delta_t
r_3 = r + 0.5*delta_t*m2
R3_3 = (r_3.dot(r_3))**1.5
#u_3 = m3
k3 = -((G*Mc)/(R3_3))*r_3
m4 = u + delta_t*k3
#t_4 = t + delta_t
r_4 = r + delta_t*m3
R3_4 = (r_4.dot(r_4))**1.5
#u_4 = m4
k4 = -((G*Mc)/(R3_4))*r_4
r = r + (delta_t/6)*(m1+2*(m2+m3)+m4)
u = u + (delta_t/6)*(k1+2*(k2+k3)+k4)
return r,u
# solução passo a passo
lim = 86400*TINTE
while t < lim:
t += delta_t
r,u = rk4(r,u)
tempo.append(t)
xc.append(r[0])
yc.append(r[1])
zc.append(r[2])
return xc,yc,zc,tempo
Inserting Data into Files
DADOS = RUNGE_KUTAH_4(X,V)
Traj = dict()
Traj['Xc'] = DADOS[0]
Traj['Yc'] = DADOS[1]
Traj['Zc'] = DADOS[2]
Traj['Tempo'] = DADOS[3]
Traj = pd.DataFrame(Traj)
Path plot based on the integrator results
def spheres(size, clr):
# Set up 100 points. First, do angles
theta = np.linspace(0,2*np.pi,100)
phi = np.linspace(0,np.pi,100)
# Set up coordinates for points on the sphere
x0 = size * np.outer(np.cos(theta),np.sin(phi))
y0 = size * np.outer(np.sin(theta),np.sin(phi))
z0 = size * np.outer(np.ones(100),np.cos(phi))
# Set up trace
trace= go.Surface(x=x0, y=y0, z=z0, colorscale=[[0,clr], [1,clr]])
trace.update(showscale=False)
return trace
Earth = spheres(6371,'#325bff')
Path = go.Scatter3d(x=Traj["Xc"], y=Traj["Yc"], z=Traj["Zc"],marker=dict(size=3),line=dict(color='pink',width=1.5))
#Terra = go.Figure(go.Scattergeo())
fig = go.Figure(data=[Earth,Path])
#fig = go.Figure(Path)
plot(fig)
The result is the one showed in the picture.
How can I animate the trajectory while keep the sphere (representing the Earth) without the previous state be deleted in a way my final result is exactly the figure I showed ?
Thanks in advance.