This is what I typically do.
nframes = 300
anim = @animate for t in LinRange(first(sol1.t), last(sol1.t), nframes)
plot(sol1, vars = (1,2,3), tspan = (0.0, t), lab = "Solution 1")
plot!(sol2, vars = (1,2,3), tspan = (0.0, t), lab = "Solution 2")
#current time marker
scatter!(sol1, vars = (1,2,3), tspan = (t, t), lab = nothing, color = 1)
scatter!(sol2, vars = (1,2,3), tspan = (t, t), lab = nothing, color = 2)
# axis setting... need to be last b/c DiffEq recipes will overwrite.
plot!(xaxis = ("x" ,(-30, 30)), yaxis = ("y", (-30,30)), zaxis=("z", (0, 60)),
title = "t = $(round(t, digits = 2))")
end
gif(anim, "myGif.gif"; fps = 30)
A couple things of note
- Inside each @animate loop you need to create a new figure, not push to an existing one. Each loop will be a frame.
- I am using a plot recipe for DiffEq. see Plot Functions · DifferentialEquations.jl
-
vars = (1,2,3)indicates to make a 3D plot of the states, 1,2,and 3. You use “0” for time. So, if you just wanted a 2D plot of x vs t you usevars = (0, 1) -
tspan = (0,t)will interpolate the solution only in that time horizon. Becausetis our loop variable it keeps growing - I also show using this for adding a scatter pt for the current time for the frame. Note how I used
tspan = (t,t)so only plotting for that time. - Plot color can be specified various ways, by giving a number as
color = 1, you specify the first in the cycle of colors. So, here I ensure the scatter colors match the other plots - Note that the DiffEq plot recipes will overwrite things like
xaxis, so I specify them last.
-
- Plotting functions appended with
!will add a new series to the previous plot. - The
fps = 30kwarg ingifspecifies the frames / s
A big advantage of this approach is the each frame will be linearly spaced in time. Depending on the integrator you use, variable time steps may be used. So, by indexing directly in the solution like you were, the animation may not look smooth in time depending on the system and integrator.