# How to get rid of noise in phase isosurface plots? Very short MWE included

**URL:** <https://discourse.julialang.org/t/how-to-get-rid-of-noise-in-phase-isosurface-plots-very-short-mwe-included/130890>\
**Category:** Visualization\
**Tags:** question, plotting, makie, glmakie, contouring\
**Created:** [July 20, 2025, 10:37pm UTC](https://discourse.julialang.org/t/how-to-get-rid-of-noise-in-phase-isosurface-plots-very-short-mwe-included/130890 "2025-07-20T22:37:59Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Deceneu](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/deceneu/32/217811_2.png) [@Deceneu](https://discourse.julialang.org/u/Deceneu)\
**Post date:** [July 20, 2025, 10:37pm UTC](https://discourse.julialang.org/t/how-to-get-rid-of-noise-in-phase-isosurface-plots-very-short-mwe-included/130890/1 "2025-07-20T22:37:59Z")

</div>

To keep it brief, I want to plot complex phase (angle) of a complex field. It seemed like Makie.jl’s contour or volume, should do the trick, but I get very noisy results for some reason?

```julia
using GLMakie

ph = [(r = hypot(x, y); ϕ = atan(x, y); angle(r*(r .- 5)*exp(1im*(2π*z/10 + ϕ)))) 
            for x in LinRange(-10, 10, 200), y in LinRange(-10, 10, 200), z in LinRange(-10, 10, 200)]

contour(ph)

```

should yield something like

 ![example](https://global.discourse-cdn.com/julialang/original/3X/0/d/0d08bca88ad6b48af0ef149e91e132f8dd6903c8.jpeg)

```julia
volume(ph, algorithm = :iso, isovalue = 0., isorange = 0.05)

```

yields

 ![example2](https://global.discourse-cdn.com/julialang/original/3X/d/4/d4e7da9b6c54745bf8bbe1ec983b7ed48a2be448.jpeg)

I don’t think this is an issue with the data. Filtering for a certain phase and then scattering

```julia
idxs_0 = filter(ijk -> -0.025 < ph[ijk...] < 0.025, 
                  collect(Iterators.product(1:200, 1:200, 1:200)))
scatter(idxs_0)

```

yields a clean plot…

 ![example3](https://global.discourse-cdn.com/julialang/original/3X/b/b/bb15052f1a580d300ade581374093f1873e090db.jpeg)

Does anyone have any experience in dealing with this issue?  
Any suggestions on how to proceed are welcome!

---

<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:** [July 21, 2025, 7:44am UTC](https://discourse.julialang.org/t/how-to-get-rid-of-noise-in-phase-isosurface-plots-very-short-mwe-included/130890/2 "2025-07-21T07:44:28Z")

</div>

have you tried setting a bigger isorange?

---

<div class="post-metadata">

**Author:** ![Deceneu](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/deceneu/32/217811_2.png) [@Deceneu](https://discourse.julialang.org/u/Deceneu)\
**Post date:** [July 21, 2025, 8:58am UTC](https://discourse.julialang.org/t/how-to-get-rid-of-noise-in-phase-isosurface-plots-very-short-mwe-included/130890/3 "2025-07-21T08:58:29Z")

</div>

Yeah, I did. it doesn’t really help.

My guess is that this is an issue with the algorithm for generating/drawing the isosurface mesh. Based on examples in Makie’s documentation, I think there’s a built-in assumption about the domain being _closed_ in some sense. Unlike here, where there are tears in the surface.

If you overlap the isosurface and the scatter plot you see that there’s no data where there is noise.

```julia
volume(ph, algorithm = :iso, isovalue = 0., isorange = 0.05)
scatter!(idxs_0, overdraw = true, markersize = 1., color = :red)

```

---

<div class="post-metadata">

**Author:** ![JonasWickman](https://avatars.discourse-cdn.com/v4/letter/j/9de0a6/32.png) [@JonasWickman](https://discourse.julialang.org/u/JonasWickman)\
**Post date:** [July 21, 2025, 1:06pm UTC](https://discourse.julialang.org/t/how-to-get-rid-of-noise-in-phase-isosurface-plots-very-short-mwe-included/130890/4 "2025-07-21T13:06:56Z")

</div>

For plotting isosurfaces, I often have more luck using the `MarchingCubes` library:

```julia
using GLMakie
using MarchingCubes
using GeometryBasics

xs = ys = zs = LinRange(-10, 10, 200)
ph = [(r = hypot(x, y); ϕ = atan(x, y); angle(r*(r .- 5)*exp(1im*(2π*z/10 + ϕ)))) 
            for x in LinRange(-10, 10, 200), y in LinRange(-10, 10, 200), z in LinRange(-10, 10, 200)]
march_cube_data = MC(ph; x = xs , y = ys , z = zs)
march(march_cube_data, 0) # 0 is the isovalue
mc_mesh = MarchingCubes.makemesh(GeometryBasics, march_cube_data)

fig = Figure()
ax = Axis3(fig[1,1])
mesh!(ax, mc_mesh; backlight = 1.0)
fig

```

which yields:

 ![iso_surface](https://global.discourse-cdn.com/julialang/original/3X/7/6/7630dcf6bed5ef9b0048c77182c894a710687691.png)

I’m not sure if you consider the middle cylinder to be noise, but since you have the expression `(r-5)` in your final expression and `angle(0.0)` is defined to be 0, I’m not sure how you would avoid it.

As a side-note, it took me a bit to parse that you have multiple expressions on one line separated by semicolons. Clearly it works, but I certainly would have found it easier to understand if it was written something like:

```julia
function calc_ph(x, y, z)
    r = hypot(x, y)
    ϕ = atan(x, y)
    ph = angle(r*(r .- 5)*exp(1im*(2π*z/10 + ϕ)))
    return ph
end
ph = [calc_ph(x, y, z) for x in xs, y in ys, z in zs]

```

---

<div class="post-metadata">

**Author:** ![Deceneu](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/deceneu/32/217811_2.png) [@Deceneu](https://discourse.julialang.org/u/Deceneu)\
**Post date:** [July 21, 2025, 2:14pm UTC](https://discourse.julialang.org/t/how-to-get-rid-of-noise-in-phase-isosurface-plots-very-short-mwe-included/130890/5 "2025-07-21T14:14:49Z")

</div>

Thank you! This is pretty much what I was hoping for! Also, no, I wouldn’t consider the center cylinder noise per-se, even though I’d prefer it not be there.

I am not very familiar with `MarchingCubes`, but I would imagine you could stop the cylinder from forming by imposing a maximum distance of points which are allowed to be joined. It also doesn’t form just for `isovalue = 0`. For

```julia
march(march_cube_data, π/2)

```

you get

 ![pi_2](https://global.discourse-cdn.com/julialang/original/3X/5/5/55d5acf660a225cc86b1c8978890d32901d74125.jpeg)

And, point taken, about the condensed block `(r = hypot(x, y); ϕ = atan(x, y); angle(r*(r .- 5)*exp(1im*(2π*z/10 + ϕ))))`. The reason I wrote it like this is because I was messing in the terminal and I absolutely _hate_ to escape the return when editing `begin` `end` blocks. I always end up evaluating instead of inserting a new line. After I got it working, I just ended up pasting it here as I knew the code snippet worked.

---

<div class="post-metadata">

**Author:** ![ffreyer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ffreyer/32/21569_2.png) [@ffreyer](https://discourse.julialang.org/u/ffreyer)\
**Post date:** [July 21, 2025, 4:24pm UTC](https://discourse.julialang.org/t/how-to-get-rid-of-noise-in-phase-isosurface-plots-very-short-mwe-included/130890/6 "2025-07-21T16:24:06Z")

</div>

The problem is that the shader samples with interpolation, so when you have a jump in your data it thinks there is a thin strip of values that should be picked. You can do `interpolate = false` to avoid this, but that also turns the render blocky:

 ![image](https://global.discourse-cdn.com/julialang/original/3X/9/4/94391d95277cae4ac3ac2fafad1d60db7e21e6fc.jpeg)
