How to Save MP4 with CairoMakie?

Hi all,

from this topic:

I want to save the animation in mp4 format, but I do not know is my code right? especially the last line to call the function as well:

using CairoMakie, Meshes

function sierpinski()
    # create observable holding scatter points
    tr = Observable(Point2f[(0, 0), (1, 0), 0.5.*(1, sqrt(3))])

    # create a scatter plot of that observable
    f, ax, sc = scatter(tr, markersize = 3)

    # create the starting point for the iterative algorithm
    m = Point2f(0.5 .* ((0,0).+ (1,0)))
    
    # make a recording of figure `f` with 300 frames
    record(f, "sierpinski.mp4", 1:300) do frame
        # add 10 new points per frame
        for i in 1:10
            # calculate a new m
            m = 0.5f0 * (m + tr[][rand(1:3)])
            # and push it to the vector contained in the observable tr
            # without updating the observable, yet
            push!(tr[], m)
        end
        # after all new points are added, update the observable tr once
        # so the scatter plot is updated as well for the new frame
        # that is being created each time that this closure returns
        notify(tr)
    end
end

save("/home/browni/LasthrimProjection/JupyterLab/CairoMakie/example.mp4",sierpinski)

record(f, "sierpinski.mp4" already saves an mp4 file, you only have to call sierpinski() after defining the function.

I got the errors:

WARNING: both Meshes and CairoMakie export “Point2f”; uses of it in module Main must be qualified
ERROR: LoadError: UndefVarError: Point2f not defined
Stacktrace:
[1] sierpinski()
@ Main ~/LasthrimProjection/JupyterLab/CairoMakie/plot.jl:5
[2] top-level scope
@ ~/LasthrimProjection/JupyterLab/CairoMakie/plot.jl:30
[3] include(fname::String)
@ Base.MainInclude ./client.jl:451
[4] top-level scope
@ REPL[1]:1
in expression starting at /home/browni/LasthrimProjection/JupyterLab/CairoMakie/plot.jl:30

In the previous CairoMakie code I used to be able to pass the “Point2f” problem by saving the media at the last line like this line:

save("/home/browni/LasthrimProjection/JupyterLab/DifferentialEquations/example.svg",fig)

The error means that referring to Point2f is ambiguous since both Meshes.jl and CairoMakie.jl export a type called Point2f. To resolve the ambiguity, you need to use either Meshes.Point2f or CairoMakie.Point2f instead of just Point2f.

1 Like

That’s a great explanation, thanks a lot!

I have a suggestion, maybe you should go with the main team of JULIA and edit all the warnings so beginner like me know what to do when they get warning.

This is the working code and the mp4 is only 194 kb:

using CairoMakie, Meshes

function sierpinski()
    # create observable holding scatter points
    tr = Observable(CairoMakie.Point2f[(0, 0), (1, 0), 0.5.*(1, sqrt(3))])

    # create a scatter plot of that observable
    f, ax, sc = scatter(tr, markersize = 3)

    # create the starting point for the iterative algorithm
    m = CairoMakie.Point2f(0.5 .* ((0,0).+ (1,0)))
    
    # make a recording of figure `f` with 300 frames
    record(f, "sierpinski.mp4", 1:300) do frame
        # add 10 new points per frame
        for i in 1:10
            # calculate a new m
            m = 0.5f0 * (m + tr[][rand(1:3)])
            # and push it to the vector contained in the observable tr
            # without updating the observable, yet
            push!(tr[], m)
        end
        # after all new points are added, update the observable tr once
        # so the scatter plot is updated as well for the new frame
        # that is being created each time that this closure returns
        notify(tr)
    end
end

sierpinski()

or perhaps just a paragraph in the manual🤣

https://docs.julialang.org/en/v1/manual/modules/#Handling-name-conflicts

2 Likes

After reading it, the warning should be like this then:

**Here, Julia cannot decide which f you are referring to, so you have to make a choice. **
Simply proceed with qualified names like A.f and B.f. click here to read more.

That will make better Julia.