# Animation images and dataframe content

**URL:** <https://discourse.julialang.org/t/animation-images-and-dataframe-content/88336>\
**Category:** Visualization\
**Tags:** animations\
**Created:** [October 6, 2022, 9:56am UTC](https://discourse.julialang.org/t/animation-images-and-dataframe-content/88336 "2022-10-06T09:56:03Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![pascal](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pascal/32/207922_2.png) [@pascal](https://discourse.julialang.org/u/pascal)\
**Post date:** [October 6, 2022, 9:56am UTC](https://discourse.julialang.org/t/animation-images-and-dataframe-content/88336/1 "2022-10-06T09:56:03Z")

</div>

I have multiple images stacked into an array:

```julia
using CairoMakie
using Images
using DataFrames
using DataFramesMeta

# Load cow
img_orig = load(Makie.assetpath("cow.png"))
img_filt1 = imfilter(img_orig, Kernel.gaussian(3))
img_filt2 = imfilter(img_orig, Kernel.gaussian(30))
img_filt3 = imfilter(img_orig, Kernel.gaussian(300))
img_bw = Gray.(img_orig)

# Combine
img_array = [img_orig;;; img_filt1;;; img_filt2;;; img_filt3;;; img_bw]

```

and a data frame with x and y coordinates as well as a colour and a frame column s.t.

```julia
df = DataFrame(x=rand(1:400, 10), y=rand(1:300, 10), c=rand(10), f=rand(1:5, 10))

```

Now, I want to create an animation (i.e. time lapse movie) where each frame corresponds to an image in the array overlayed with dots defined by the dataframe. So far I have the following but cannot figure out how to properly animate, record and save it.

```julia
frame_i = Observable(1)

df_i = @lift(@rsubset(df, :f == $frame_i))
img_i = @lift(img_array[:, :, $frame_i])

# Plot
function _plt_fig(frame)

    frame_i[] = frame
    fig = Figure()
    ax = CairoMakie.Axis(fig[1, 1])

    image!(ax, rotr90(img_i.val))
    scatter!(ax, df_i.val.x, df_i.val.y, color=df_i.val.c, markersize=30)

    return fig
end

```

Any help would be greatly appreciated.

---

<div class="post-metadata">

**Author:** ![johnh](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/johnh/32/3615_2.png) [@johnh](https://discourse.julialang.org/u/johnh)\
**Post date:** [October 6, 2022, 11:10am UTC](https://discourse.julialang.org/t/animation-images-and-dataframe-content/88336/2 "2022-10-06T11:10:56Z")

</div>

For saving as a video I think VideoIO.jl would help

---

<div class="post-metadata">

**Author:** ![pascal](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pascal/32/207922_2.png) [@pascal](https://discourse.julialang.org/u/pascal)\
**Post date:** [October 7, 2022, 7:32am UTC](https://discourse.julialang.org/t/animation-images-and-dataframe-content/88336/3 "2022-10-07T07:32:47Z")

</div>

Thanks @johnh. With `VideoIO.save` I could save an image stack to .mp4 for instance.  
Which brings me to another way to approach this problem.

I could also flatten the dataframe data into the image such that I get one new image from this and save these to a new stack and write them out to a video. I, however, also do not know how to do this “flattening”.

---

<div class="post-metadata">

**Author:** ![pascal](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pascal/32/207922_2.png) [@pascal](https://discourse.julialang.org/u/pascal)\
**Post date:** [October 7, 2022, 8:03am UTC](https://discourse.julialang.org/t/animation-images-and-dataframe-content/88336/4 "2022-10-07T08:03:35Z")

</div>

Alright… I’ve figured it out:

```julia
using CairoMakie
using Images
using DataFrames
using DataFramesMeta

# Load cow
img_orig = load(Makie.assetpath("cow.png"))
img_filt1 = imfilter(img_orig, Kernel.gaussian(3))
img_filt2 = imfilter(img_orig, Kernel.gaussian(30))
img_filt3 = imfilter(img_orig, Kernel.gaussian(300))
img_bw = Gray.(img_orig)

# Combine
img_array = [img_orig;;; img_filt1;;; img_filt2;;; img_filt3;;; img_bw]

# Data
df = DataFrame(x=rand(1:400, 10), y=rand(1:300, 10), c=rand(10), f=rand(1:5, 10))

frame_i = Observable(1)

df_i = @lift(@rsubset(df, :f == $frame_i))
img_i = @lift(img_array[:, :, $frame_i])

fig = Figure()
ax = CairoMakie.Axis(fig[1, 1])

# Plot
function _plt_fig!(frame)

    frame_i[] = frame
    image!(ax, rotr90(img_i.val))
    scatter!(ax, df_i.val.x, df_i.val.y, color=df_i.val.c, markersize=30)
    return fig
end

frames = 1:5
record(fig, "video.mp4", frames; framerate=1) do i
        _plt_fig!(i)
end

```
