# Plot lots of surfaces with normals

**URL:** <https://discourse.julialang.org/t/plot-lots-of-surfaces-with-normals/129377>\
**Category:** Visualization\
**Tags:** wglmakie\
**Created:** [May 27, 2025, 12:35pm UTC](https://discourse.julialang.org/t/plot-lots-of-surfaces-with-normals/129377 "2025-05-27T12:35:50Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![weymouth](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/weymouth/32/15839_2.png) [@weymouth](https://discourse.julialang.org/u/weymouth)\
**Post date:** [May 27, 2025, 12:35pm UTC](https://discourse.julialang.org/t/plot-lots-of-surfaces-with-normals/129377/1 "2025-05-27T12:35:51Z")

</div>

I have an array of named tuples, each of which describes a 3D panel. Panels corners, centers, areas, normal vector, etc. I want to plot the panels and be able to apply a color to each one. I would like to use `Plots` and `plotlyjs()` so it’s easy to interact with in a Pluto notebook. The fallback can be `gr()`.

The problem I’m having is that I need to plot the panels 1-by-1 to apply the array of colors, but this is super slow. Even slower if I want to add the normal arrow to each. I tried plotting the quiver after all the panels, but the z-ordering doesn’t work!

---

<div class="post-metadata">

**Author:** ![sdanisch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sdanisch/32/1406_2.png) [@sdanisch](https://discourse.julialang.org/u/sdanisch)\
**Post date:** [May 27, 2025, 2:40pm UTC](https://discourse.julialang.org/t/plot-lots-of-surfaces-with-normals/129377/2 "2025-05-27T14:40:30Z")

</div>

Could you use WGLMakie for Pluto?

---

<div class="post-metadata">

**Author:** ![weymouth](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/weymouth/32/15839_2.png) [@weymouth](https://discourse.julialang.org/u/weymouth)\
**Post date:** [May 27, 2025, 4:34pm UTC](https://discourse.julialang.org/t/plot-lots-of-surfaces-with-normals/129377/3 "2025-05-27T16:34:22Z")

</div>

This is exactly what I ended up doing Simon. It is \<chef’s kiss\> soooo nice. And super fast.

```julia
function viz(panels, values; vectors=panels.n, colormap=:viridis)
    fig = Figure()
    ax = Axis3(fig[1, 1], aspect=:data)

    # Normalize and map to color
    vmin, vmax = extrema(values)
    norm_vals = (values .- vmin) ./ (vmax - vmin + eps())
    colors = cgrad(colormap)[norm_vals]

    # Mesh geometry (triangle list) and colors
    triangles = mapreduce(vcat, panels) do panel
        p = panel.corners
        [p[1], p[2], p[3], p[4], p[3], p[2]]
    end
    tri_colors = mapreduce(c -> fill(c, 6), vcat, colors)
    mesh!(ax, triangles; color=tri_colors)

    # Normals & color bar
    components(data) = ntuple(i -> getindex.(data, i), 3)
    arrows!(ax, components(panels.x)..., components(vectors)...; color=colors)
    Colorbar(fig[1, 2], limits=(vmin, vmax); colormap)
    fig
end

```

---

<div class="post-metadata">

**Author:** ![weymouth](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/weymouth/32/15839_2.png) [@weymouth](https://discourse.julialang.org/u/weymouth)\
**Post date:** [May 28, 2025, 10:15am UTC](https://discourse.julialang.org/t/plot-lots-of-surfaces-with-normals/129377/4 "2025-05-28T10:15:36Z")

</div>

@sdanisch I have a follow-up (maybe belongs in the new question). One feature of this boundary element method is that the panels aren’t really planar, and using two triangles might give the wrong impression. Is there a way to “fake” a smoother surface?

 ![Screen Shot 2025-05-28 at 12.19.42](https://global.discourse-cdn.com/julialang/original/3X/a/8/a845c37c098457fe8620762521a0449d416f2878.png)

I have the corner points, the center point, and the normal at the center. I tried making four triangles between the corners and center, but this looks even more “pointy”. Can I apply my panel-center normal to the shader for all four of those triangle so the light is more uniform on them?

 ![Screen Shot 2025-05-28 at 12.17.06](https://global.discourse-cdn.com/julialang/original/3X/4/e/4e90385147995b037fb9125a3553882b3e4d99f1.png)

---

<div class="post-metadata">

**Author:** ![sdanisch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sdanisch/32/1406_2.png) [@sdanisch](https://discourse.julialang.org/u/sdanisch)\
**Post date:** [May 28, 2025, 11:21am UTC](https://discourse.julialang.org/t/plot-lots-of-surfaces-with-normals/129377/5 "2025-05-28T11:21:08Z")

</div>

I’m not 100% sure if I understand you correctly, but I think calculating a normal for each point should do the trick.  
Best, by averaging over neighboring normals.

---

<div class="post-metadata">

**Author:** ![weymouth](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/weymouth/32/15839_2.png) [@weymouth](https://discourse.julialang.org/u/weymouth)\
**Post date:** [May 28, 2025, 11:46am UTC](https://discourse.julialang.org/t/plot-lots-of-surfaces-with-normals/129377/6 "2025-05-28T11:46:27Z")

</div>

This is certainly another question now… 😉 I’ll ask on slack.
