I am using the (semi-)documented contour function for 3D-isosurfaces, cf. volume | Makie, first example.
One cannot define vector of alphas (which would be nice because outer surfaces (shells) “should” be more transparent.
Thus I came up with the following code:
using Statistics, GLMakie, LinearAlgebra
_iscollection(x) = x isa Union{AbstractArray, Tuple, AbstractRange}
# Cycle collections; repeat scalars
_as_iter(x, n) = _iscollection(x) ? Iterators.take(Iterators.cycle(x), n) :
Iterators.repeated(x, n)
function new_iso_contour3d!(
vol::AbstractArray;
xs = (1, size(vol, 1)), ys = (1,size(vol, 2)), zs = (1,size(vol, 3)),
ax = current_axis(),
levels = quantile(vol, [0.25, 0.50, 0.75]),
colors = [:yellow, :orange, :red],
alphas = [0.05, 0.1, 0.2],
)
lvls = levels isa Number ? (levels, ) : collect(levels)
L = length(lvls)
cols = collect(_as_iter(colors, L))
als = collect(_as_iter(alphas, L))
ivx, ivy, ivz = extrema(xs), extrema(ys), extrema(zs)
for (lev, col, a) in zip(lvls, cols, als)
contour!(ax, ivx, ivy, ivz, vol;
levels=[lev], colormap=cgrad([col, col]), alpha=a)
end
nothing
end
r = range(-1, 1, length=20)
vol = [norm([1.2x,y,z]) for x=r, y=r, z=r]
fig = Figure()
ax = LScene(fig[1, 1], scenekw=(show_axis=true,))
new_iso_contour3d!(vol[1:10,:,:]; xs=0.5r, ys=r, zs=r,
levels=[0.1, 0.5, 0.8], colors=[:red, :orange, :yellow], alphas=[0.2, 0.1, 0.05])
Now, my problem is that the isosurfaces are very thick:
I also tried volume(algorithm=:iso,…) and then a thin isorange, but with smaller alpha the surfaces are really grey. So it would be nice to have control over isorange also from the contour function (?).
I want to plot something, that looks similar to this one below (some years ago with R):
Maybe it is just a matter of the settings in volume(algorithm=:iso,…). Or maybe one can do with surface
, but I would not know how exactly. (still new to Julia).
Thanks for any help!