Plotting with Makie safe frames

Hi there,

I’m new in the world of Julia. At the moment I’m working on a little project developing a solver on my GPU. To plot my results I’m using Makie.jl since I’m working on the GPU anyway.
So far I used the Makie.record command to record my solution evolving in time, but I want to edit some details in the video and therefore it seems to be reasonable just to save the plots at every single time step as a .png and render all pictures afterwards in a separate program. Unfortunately I run into problems using the following little sample code ( initial_data just return a 3D Arrays depending on the vector k_in)

using Makie
using CuArrays
for i=1:10
    scene = Scene()
    z=initial_data(N, k_in, x_min, x_max, y_min, y_max, z_min, z_max)
    Makie.volume!(scene, real(z), algorithm=:iso, isovalue=alpha,transparency=true,color=:red)"test$i.png", scene)

Here all timesteps are plottet into a single scene which is definetly nowt what I want, by neglecting the broadcast command ! I run into the following error

ERROR: LoadError: No overload for Volume{...} and also no overload for trait AbstractPlotting.VolumeLike() found! Arguments: (Scene, Array{Float64,3})
 [1] #convert_arguments#214(::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}, ::Function, ::Type{Volume{...}}, ::Scene, ::Vararg{Any,N} where N) at C:\Users\Noobie\.julia\packages\AbstractPlotting\NOT5R\src\conversions.jl:54
 [2] convert_arguments(::Type{Volume{...}}, ::Scene, ::Array{Float64,3}) at C:\Users\Noobie\.julia\packages\AbstractPlotting\NOT5R\src\conversions.jl:49
 [3] #plot!#195(::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}, ::Function, ::Scene, ::Type{Volume{...}}, ::Attributes, ::Scene, ::Vararg{Any,N} where N) at C:\Users\Noobie\.julia\packages\AbstractPlotting\NOT5R\src\interfaces.jl:494
 [4] plot!(::Scene, ::Type{Volume{...}}, ::Attributes, ::Scene, ::Array{Float64,3}) at C:\Users\Noobie\.julia\packages\AbstractPlotting\NOT5R\src\interfaces.jl:481
 [5] #volume#96(::Base.Iterators.Pairs{Symbol,Any,NTuple{4,Symbol},NamedTuple{(:algorithm, :isovalue, :transparency, :color),Tuple{Symbol,Int64,Bool,Symbol}}}, ::Function, ::Scene, ::Vararg{Any,N} where N) at C:\Users\Noobie\.julia\packages\AbstractPlotting\NOT5R\src\recipes.jl:17
 [6] (::getfield(AbstractPlotting, Symbol("#kw##volume")))(::NamedTuple{(:algorithm, :isovalue, :transparency, :color),Tuple{Symbol,Int64,Bool,Symbol}}, ::typeof(volume), ::Scene, ::Array{Float64,3}) at .\none:0
 [7] top-level scope at C:\Users\Noobie\Documents\TESTJULIAGPU\03\testplotpng.jl:9 [inlined]
 [8] top-level scope at .\none:0
in expression starting at C:\Users\Noobie\Documents\TESTJULIAGPU\03\testplotpng.jl:5

So my question is if there is some way to clear your scene before plotting the next time step and store it into a .png file? Or there are other useful tools in Makie.record to achieve something similar? I don’t find anything useful for my concrete problem in the Makie documentation.

PS: I have one further little question, is there any similar string formatting operator as %04d in Phyton to name your output files in the following manner test0001.png,test0002.png ,… . This would be very convenient for post-processing.


but I want to edit some details in the video and therefore it seems to be reasonable just to save the plots at every single time step as a .png

What video editing software do you use, that doesn’t support importing videos? :smiley:

Anyways, this is how you should do this:

using Makie, FileIO, Printf
# initialize plot
z = zeros(Float32, 200, 200, 200)
scene = Makie.volume(z, algorithm=:iso, isovalue=alpha,transparency=true,color=:red)
volplot = scene[end] # last plot
screen = display(scene) 
for i in 1:10
    k_in = [i, -i, i^2]
    z2 = initial_data(N, k_in, x_min, x_max, y_min, y_max, z_min, z_max)
    # update first argument (volume(z)) with new values in place
    volplot[1] = (z .= Float32.(real.(z2)))
    # Save colorbuffer (more efficient then save(scene))
    save(@sprintf("test_%04d.png", i) , AbstractPlotting.colorbuffer(screen))

I’m using OpenShot, I achieve the best output by doing so :smiley:


sry I have to ask you a last question,. First your sample codes works well, but I can’t apply it in the 2D case, when I not want to plot the evolution a a single component. But I’m very confused about the data types and I can’t adapt your code above to that circumstances. Here x denotes a vector which entries are my grid points in the x-direction

#initialize the scene
z=CuArrays.zeros(ComplexF64, Jx)
    scene = Makie.lines(x,z)
    volplot = scene[end] # last plot
    screen = display(scene)

for t=1:M

...update z...

    volplot[1] = ((x,z) .= tuple.(x,real(z))
    save(@sprintf("test_%04d.png", t) , AbstractPlotting.colorbuffer(screen))


What did I do? First I looked up the data type of scene[end][1] and it gives me

Observable{Array{Point{2,Float32},1}} with 2 listeners. Value: ...

Then I said to me if the above syntax works for the volume plot then I just should do something natural similar in the case of lines(). But this ended up in an error message, also slight variations and multiple searches at the Makie.jl side didn’t bring the enlightenment.

Can u maybe help me by explaining what scene[end] exactly represents and how I can overhand the data that I want to its first component [1] exactly?

Thank you in any case!