What's a good way to create an animation from a timestamped image sequence?

I am doing an event-based simulation, that gets updated when each event happens. For simplicity’s sake, assume it’s a simple Poisson process that creates a random 100x100 matrix when each event happens. So we’ll have a series of matrices with the time they happened. Interpreting the matrices as grayscale images, the data would be a timestamped image sequence. How can I animate this sequence?

I have searched around, and the best idea I have found so far is to save the images with specific modification timestamps, and use the image2 demuxor from ffmpeg with ts_from_file 2 that uses the modification times as frame timestamps. But this is a rather clunky solution …

VideoIO.jl can write your frames to an mp4 file.

using VideoIO, Distributions

encodevideo("noise.mp4", [rand(Poisson(100), (100, 100)) for _ in 1:60], framerate=30)

I don’t know of any video formats that allow irregularly spaced frames, so if your timestamps are not regular you will have to interpolate/decimate using a technique appropriate to your data and then save at a fixed frame rate.

You could use https://makie.juliaplots.org/dev/animation.html#Animation

I found some good answers here. Here is one way using imshow:

using Images, ImageView, Gtk, TestImages, GtkReactive
data = [...]
imgsig = Signal(data[1])
guidict = imshow_gui((300, 300))
canvas = guidict["canvas"]
Gtk.showall(guidict["window"])
imshow(canvas, imgsig)
begin
    for i in 2:length(data)
        push!(imgsig, data[i])
        sleep(0.05)
    end
end

Gif is simple, something like:

using FileIO, Colors
sequence = cat(map(matrix -> RGB4.(matrix), matrices)..., dims=3)
FileIO.save("test.gif", sequence; fps=25)

The problem is that my frames will be irregularly timed. (E.g., one frame, sleep 2.3, another frame, sleep 0.3, …)

Like @contradict said, you will likely need to separate the irregular timings of your data from the regularly timed framerate.

I’ve had some good luck with time-sensitive animations and timings using this package:

It’s a simple package and is not connected to any image framework, which is what made it useful to me. Here’s a sample from its docs:

using Animations
anim = Animation(
    0, 1.0, # t = 0, value = 1
    sineio(),
    1, 2.0,   # t = 1, value = 2
    linear(),
    2, 3.0    # t = 2, value = 3
)

There are more ways to create the animations, but I think you could essentially use the t values to indicate the keyframe values of your data. Something like this, maybe:

anim = Animation(
    0, 1.0,
    noease(),
    rel(2.3), 2.0, # sleep 2.3
    noease(),
    rel(0.3), 3.0 # sleep 0.3
)

When you create the animation (gif, mp4, etc), you can generate each frame to be written by iterating over anim, and plugging in the values it returns (1.0, 2.0, 3.0 in this case) to generate or fetch your matrix data.

Also you might be able to use DynamicGrids.jl for the whole simulation, and get all the outputs for free (it will print text of the timestamp onto the live output/gif, the REPL).

The problem is that my frames will be irregularly timed. (E.g., one frame, sleep 2.3, another frame, sleep 0.3, …)

I missed this sorry. But you do need a fixed frame-rate at some stage…

I would just choose one at the start (it can be high) and round your events to the frame rate.