Makie surface and NaN values

I am running in some unexpected behavior with GLMakie, surface plots and matrices that contain NaN as a value.

My minimum working example below produces the following plots of three different 4 x 4 matrices with different elements set to NaN:

  1. What causes the darker shading of cells adjacent to a NaN value?
  2. The right most example is, frankly, somewhat weird to me (why is the surface dropping to a low value and becomes transparent like this?)

The behavior that I would like to have is that all tiles that have a NaN value as one of its vertices are simply not displayed. Is this doable with some tinkering of attributes of the surface?

Here the MWE code reproducing the above figures:

using GLMakie

x = 0.0:3.0
y = 0.0:3.0
Z1 = reshape([100*i+50*j for i in x for j in y], (length(x), length(y)))
Z2 = copy(Z1)
Z3 = copy(Z1)

Z2[1,1] = NaN
Z3[1:2, 1:2] .= NaN

f = Figure(resolution = (800, 800))
ax1 = Axis3(f[1, 1], aspect = (1, 1, 1))
ax2 = Axis3(f[1, 2], aspect = (1, 1, 1))
ax3 = Axis3(f[1, 3], aspect = (1, 1, 1))

surface!(ax1,x,y,Z1)
surface!(ax2,x,y,Z2)
surface!(ax3,x,y,Z3)

Just for reference, linking a related issue here, for which did not get an answer.

The behavior in your post is actually what I want. Smooth edges would be nice, I agree with you on that, but I would actually settle for what you already had!

The problem is, however, that your code produces a completely different looking image on the most current Makie version. It now shows similar issues as are shown above, but since your z-values are negative, the surface doesn’t go down like in my right hand side image, but up (towards 0).

edit: Included an image for reference.

1 Like

Empirical tip for the latest Makie version: replace NaN by Inf

PS: but result is still not shaved though…

The shader computes normals using the surrounding grid positions. If those have weird values the normals will have weird values and the lighting calculation will do weird things. Setting shading = false should get rid of the dark rectangles (or alternatively setting diffuse=Vec3f0(0), specular = Vec3f0(0)).

@ffreyer, fyi none of your solutions worked for me. The result is still as displayed by @vettert for the truncated paraboloid example.

using GLMakie

x = 0.0:3.0
y = 0.0:3.0
Z1 = reshape([100*i+50*j for i in x for j in y], (length(x), length(y)))
Z2 = copy(Z1)
Z3 = copy(Z1)

Z2[1,1] = NaN
Z3[1:2, 1:2] .= NaN

f = Figure(resolution = (800, 800))
ax1 = Axis3(f[1, 1], aspect = (1, 1, 1))
ax2 = Axis3(f[1, 2], aspect = (1, 1, 1))
ax3 = Axis3(f[1, 3], aspect = (1, 1, 1))

surface!(ax1,x,y,Z1,shading=false)
surface!(ax2,x,y,Z2,shading=false)
surface!(ax3,x,y,Z3,shading=false)

This does get rid of the darker rectangles for me. Changing shading requires you to close the window beforehand though.

The reason for the surface to drop like it does is that the shader converts nan values to 0. You could work around that by passing the modified z-values as colors, i.e.

surface!(ax3,x,y,Z1,shading=false, color = Z3)

I guess for a smooth cut we’d need a shader discarding pixels that are outside some value range or more generally a shape

Thanks to both of you @ffreyer and @rafael.guerra. Here is the full code that gets close to what I wanted.

using GLMakie

x = 0.0:3.0
y = 0.0:3.0
Z1 = reshape([100*i+50*j for i in x for j in y], (length(x), length(y)))
Z2 = copy(Z1)
Z3 = copy(Z1)
Z4 = copy(Z1)
Z5 = copy(Z1)


Z2[1,1] = NaN
Z3[1:2, 1:2] .= NaN
Z4[1,1] = Inf
Z5[1:2, 1:2] .= Inf

f = Figure(resolution = (800, 800))
ax1 = Axis3(f[1, 1], aspect = (1, 1, 1))
ax2 = Axis3(f[1, 2], aspect = (1, 1, 1))
ax3 = Axis3(f[1, 3], aspect = (1, 1, 1))
ax4 = Axis3(f[2, 2], aspect = (1, 1, 1))
ax5 = Axis3(f[2, 3], aspect = (1, 1, 1))

s1 = surface!(ax1,x,y,Z1)
s2 = surface!(ax2,x,y,Z2)
s3 = surface!(ax3,x,y,Z3)
s4 = surface!(ax4,x,y,Z4, shading = false)
s5 = surface!(ax5,x,y,Z5, shading = false)

display(f)

The smooth cut thing is of course nice to have, but in my use example, I am fine with just making the grid finer and minimizing how well one sees the rugged edges (the visualization is not the computationally expensive part of the process :slight_smile: )

NB: using Inf workaround as indicated further above.

1 Like