Makie volume animation froze!

Super simple Makie animation question. I am just trying to make a video from a volume() render of a field. I tried

a = zeros(n,n,n)
scene = volume(a)
record("file.mp4",1:100) do i
   func!(a)
   scene = volume!(scene,a)
end

But this froze my computer!

1 Like

That’s because you have added a hundred volumes to your scene.

The way to do it is with Observables (Nodes in Makie):

a = Node(zeros(n, n, n))

scene = volume(a)

# Then in the record loop:

a[] = func(a[])
2 Likes

Or:

a = zeros(n,n,n)
scene = volume(a)
vol_plot = scene[end] # end --> last plot
record("file.mp4",1:100) do i
   func!(a)
   vol_plot[1] = a # update values passed by first argument
end
1 Like

This worked. Is there somewhere that explains scene[end][1]?

1 Like

It means last plot in the scene, first positional argument of that plot. As positional arguments are always internally converted to observables this lets you change the observable as if you had created it yourself and passed it in

1 Like

http://makie.juliaplots.org/dev/animation.html
http://makie.juliaplots.org/dev/interaction.html

1 Like

Thanks. The Node documentation is clear now. I didn’t understand that the empty index a[] was triggering the update. Is there a more explicit way to do that?

The only place on the animation page I see the [end]-style used is in this example.

http://makie.juliaplots.org/dev/animation.html#More-complex-examples

where index [3] is used since the third argument was z. Is that right?

exactly!

Is there a more explicit way to do that?

not really. The syntax to update a node (observable) is this:

observable[] = new_value

Like updating a reference :wink:
Which is the key abstraction in Observables.jl. You can think of it as references with event listeners!

3 Likes

Thanks for the help. Here’s a couple of samples
ezgif.com-video-to-gif
ezgif.com-gif-maker

17 Likes

Was that made with WaterLily, or what’s the source?

WaterLily. I’ve add these two cases in the examples.

Impressive !
Do you plan to add a mathematical description of the code (the immersed boundary method) ?

Well, the paper is here: Accurate Cartesian-grid simulations of near-body flows at intermediate Reynolds numbers - ePrints Soton. I’ve only implemented first-order in WaterLily so far.

1 Like

Thank you very much !
It could be useful to insert the link in the WaterLily’s README.jl

You’re right; I shouldn’t point to a paywall! Done.

Sorry to resurrect this, but I’ve got another n00b issue. It seems like all the volume plot methods are set up for sequential data (colorrange=(0,1) where 0 is background and 1 is what we want to visualize) but what about divergent data? Is there something for colorrange=(-1,1) where 0 is background and +1 is one extreme and -1 is the other?

Alternatively, is there some way to achieve isovalue=(-1,1)? Doing two plots with isovalue=-1 and isovalue=1 doesn’t work since the second one just overlays the first and so they don’t line up three-dimensionally as they should.

Twitter post for context:

with contour, you basically get multiple iso value plots in one plot, with correct transparency:

contour(rand(4, 4, 4), levels=[-1.0, 1.0])

Is there something for colorrange=(-1,1) where 0 is background and +1 is one extreme and -1 is the other?

I’m not sure what you mean … You can use whatever colormap you want :wink:
colormap=any_array_of_colors

1 Like

contour:man_facepalming: (I guess I was more tired than I thought last night.)

I’m not sure what you mean … You can use whatever colormap you want :wink:
colormap=any_array_of_colors

For the volume rendering, I’m not looking for a color map, but an alpha or absorption map. So, maybe like absorption=[-1,1] so that regions that are both below -1 and above 1 show up in the volume plot (as different colors), but not regions with values around 0.

For example, I coded this up long ago (in Fortran, because I’m a masochist)
image

Here is version using :mip


And here is the version using :absorption

Neither shows the structures very clearly.

How does it look with with contour?
Also, you can use transparent colors e.g:

cmap = :thermal
colors = to_colormap(cmap)
cmap_alpha = RGBAf0.(colors, LinRange(0, 1, length(colors)))