3
votes

I'm trying to create an animation in Julia where a satellite orbits Earth. Earth in this case is represented by a static circle and the satellite's trajectory is a path extending from the launch point to the satellite's current position.

If I understand the process correctly, to create a gif in Julia, I need to use the @gif macro with a loop and create the next gif frame on each iteration of the loop. I've been attempting to plot Earth, then plot the launch point, then push the next position in the satellite's trajectory on each loop iteration, but it's pushing data to the Earth dataset.

I also have other plots that I would like to animate, but the animation examples that use multiple data series don't specify any x values. I need to specify x and y values for each datapoint in each series.

How can I specify the series to push a new point to?

1
It would be great if you could provide a minimal working example of what you've tried so far, so that people here can copy-paste and run your code to revise/improve it.Benoit Pasquier

1 Answers

2
votes

Well, while trying to put together a small example script, I figured it out.

To begin, the conditions under which you can use push! with a plot are fairly specific. You can't use an Int64 (or any other type of integer) as an x value or push! will try to access the plot like an array at the "index" specified by your x data. This means you have to ensure every input is a Float (I didn't try this with more exotic data types for plotting like Bools, but I assume that that wouldn't go well either).

Also, the x and y (and z) data in a plot can't be something that push! doesn't work on normally, like a StepRangeLen (e.g. t = 0:10). Unfortunately this introduces an extra layer of complexity; if you need to use StepRangeLens in your plots, you'll have to convert them to Arrays: t = Array{Float64}(0:10).

Finally, it's probably good practice to pass in as many x and y values on each call to push! as you have series (if this wording is awkward, see the example below). Some of the examples for the Plots package add complexity in specifying a single x value for multiple y values, which is fine if your x values are the same for both series, but becomes a problem if they're different.

Putting all of this together, here's a minimal example of pushing to different series:

using Plots

# Let x and z be two different-valued, different-length vectors
x = Array{Float64}(range(0, stop=π, length=30))
z = Array{Float64}(range(0, stop=-π, length=20))
p = plot(x,sin.(x))
plot!(p, z, cos.(z))

# Pushing a single x,y pair goes to the first series:
push!(p, 0.0, -0.5)

# Pushing a single x value and a 2x1 Array sends the x value to
# both series, the first y value to the first series, and the
# second y value to the second series.
push!(p, -0.2, [-0.75, 0.2])
# Note:        comma ^ is important

# Pushing two x values and two y values sends the first x value to
# the first series and the second x value to the second series.
# Same for the y values, which is the same as the previous example
push!(p, [-π/4, π/4], [0.1, 0.2])

# If you want to push only to one series, send a NaN to the others:
push!(p, [NaN, -3π/2], [NaN, 1.0])

display(p)

The plot is pretty incoherent if you run this as-is. I recommend commenting out each of the push! statements and uncommenting each one individually to see its effect on the plot.