# How to Save MP4 with CairoMakie?

**URL:** <https://discourse.julialang.org/t/how-to-save-mp4-with-cairomakie/91691>\
**Category:** General Usage\
**Tags:** package\
**Created:** [December 15, 2022, 10:06am UTC](https://discourse.julialang.org/t/how-to-save-mp4-with-cairomakie/91691 "2022-12-15T10:06:09Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Freya\_the\_Goddess](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/freya_the_goddess/32/36835_2.png) [@Freya\_the\_Goddess](https://discourse.julialang.org/u/Freya_the_Goddess)\
**Post date:** [December 15, 2022, 10:06am UTC](https://discourse.julialang.org/t/how-to-save-mp4-with-cairomakie/91691/1 "2022-12-15T10:06:09Z")

</div>

Hi all,

from this topic:

> [@How to animate Sierpinski triangle construction](https://discourse.julialang.org/t/how-to-animate-sierpinski-triangle-construction/91315):
>
> How do I get an animated gif from the following construction? Possibly also changing the functions used, if a different function is more suitable for the case. using Plots gr() tr=[(0,0),(1,0),0.5.\*(1,sqrt(3))] p=plot(tr, st=:scatter, markersize=3, legend=false) m=0.5 .\* ((0,0).+ (1,0)) sierpinski=[m] for i in 1:10000 m=0.5 .\*(m .+ tr[rand(1:3)]) push!(sierpinski,m) end plot!(p,sierpinski,st=:scatter, markersize=1, legend=false) savefig(p,"sierpinski.png") ![sierpinski|600x400](uploa…

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:

```julia
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)

```

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [December 15, 2022, 11:07am UTC](https://discourse.julialang.org/t/how-to-save-mp4-with-cairomakie/91691/2 "2022-12-15T11:07:56Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Freya\_the\_Goddess](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/freya_the_goddess/32/36835_2.png) [@Freya\_the\_Goddess](https://discourse.julialang.org/u/Freya_the_Goddess)\
**Post date:** [December 15, 2022, 11:47am UTC](https://discourse.julialang.org/t/how-to-save-mp4-with-cairomakie/91691/3 "2022-12-15T11:47:19Z")

</div>

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:

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

```

---

<div class="post-metadata">

**Author:** ![barucden](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/barucden/32/26154_2.png) [@barucden](https://discourse.julialang.org/u/barucden)\
**Post date:** [December 15, 2022, 1:14pm UTC](https://discourse.julialang.org/t/how-to-save-mp4-with-cairomakie/91691/4 "2022-12-15T13:14:16Z")

</div>

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`.

---

<div class="post-metadata">

**Author:** ![Freya\_the\_Goddess](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/freya_the_goddess/32/36835_2.png) [@Freya\_the\_Goddess](https://discourse.julialang.org/u/Freya_the_Goddess)\
**Post date:** [December 16, 2022, 12:32pm UTC](https://discourse.julialang.org/t/how-to-save-mp4-with-cairomakie/91691/5 "2022-12-16T12:32:27Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Freya\_the\_Goddess](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/freya_the_goddess/32/36835_2.png) [@Freya\_the\_Goddess](https://discourse.julialang.org/u/Freya_the_Goddess)\
**Post date:** [December 16, 2022, 12:40pm UTC](https://discourse.julialang.org/t/how-to-save-mp4-with-cairomakie/91691/6 "2022-12-16T12:40:34Z")

</div>

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

```julia
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()

```

---

<div class="post-metadata">

**Author:** ![cormullion](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cormullion/32/49131_2.png) [@cormullion](https://discourse.julialang.org/u/cormullion)\
**Post date:** [December 16, 2022, 12:41pm UTC](https://discourse.julialang.org/t/how-to-save-mp4-with-cairomakie/91691/7 "2022-12-16T12:41:20Z")

</div>

or perhaps just a paragraph in the manual🤣

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

---

<div class="post-metadata">

**Author:** ![Freya\_the\_Goddess](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/freya_the_goddess/32/36835_2.png) [@Freya\_the\_Goddess](https://discourse.julialang.org/u/Freya_the_Goddess)\
**Post date:** [December 16, 2022, 12:44pm UTC](https://discourse.julialang.org/t/how-to-save-mp4-with-cairomakie/91691/8 "2022-12-16T12:44:35Z")

</div>

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.
