# Point Occlusion in 3D Scatter Makie

**URL:** https://discourse.julialang.org/t/point-occlusion-in-3d-scatter-makie/95413
**Category:** Visualization
**Tags:** question, plotting, makie
**Created:** [March 1, 2023, 10:09pm UTC](https://discourse.julialang.org/t/point-occlusion-in-3d-scatter-makie/95413 "2023-03-01T22:09:58Z")
**Posts on this page:** 15
**Page:** 1

<div class="post-metadata">

### Author: ![Jordan\_Cluts](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jordan_cluts/32/13753_2.png) [@Jordan\_Cluts](https://discourse.julialang.org/u/Jordan_Cluts)
#### Post date: [March 1, 2023, 10:09pm UTC](https://discourse.julialang.org/t/point-occlusion-in-3d-scatter-makie/95413/1 "2023-03-01T22:09:58Z")

</div>

When I create a 3D scatter plot in Makie some of the points that are “closer” to the camera are plotted behind points that are further from the camera. This can make the plots harder to interpret. Is there a setting or technique to change or improve this behavior?

The below image shows what I mean where some points that are higher on the z-axis and therefore closer to the camera (lighter color)are plotted behind points that are lower down and further from the camera.

 ![PointOcclusion](https://global.discourse-cdn.com/julialang/original/3X/8/a/8adaa357a12dcda8ef89f7038a1122e56bd64749.png)

---

<div class="post-metadata">

### Author: ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)
#### Post date: [March 1, 2023, 10:44pm UTC](https://discourse.julialang.org/t/point-occlusion-in-3d-scatter-makie/95413/2 "2023-03-01T22:44:46Z")

</div>

I think this problem might be specific to Plots’ `gr` backend.  
See this other [post](https://discourse.julialang.org/t/how-to-plot-curve-over-surface-with-plots-jl/72498) and this [issue](https://github.com/jheinen/GR.jl/issues/446).

It doesn’t happen for instance with `plotlyjs` or `pythonplot` backends.

**NB:**  
the `gaston` backend seems to have the same limitation.

---

<div class="post-metadata">

### Author: ![Jordan\_Cluts](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jordan_cluts/32/13753_2.png) [@Jordan\_Cluts](https://discourse.julialang.org/u/Jordan_Cluts)
#### Post date: [March 1, 2023, 11:44pm UTC](https://discourse.julialang.org/t/point-occlusion-in-3d-scatter-makie/95413/3 "2023-03-01T23:44:02Z")

</div>

My apologies I completely neglected to mention in my post that this is Makie.jl. I have edited to make that clear. My deepest apologies.

---

<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: [March 2, 2023, 10:37am UTC](https://discourse.julialang.org/t/point-occlusion-in-3d-scatter-makie/95413/4 "2023-03-02T10:37:36Z")

</div>

I can’t reproduce this. Can you set up some example code? Also which backend is this?

---

<div class="post-metadata">

### Author: ![Jordan\_Cluts](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jordan_cluts/32/13753_2.png) [@Jordan\_Cluts](https://discourse.julialang.org/u/Jordan_Cluts)
#### Post date: [March 2, 2023, 2:15pm UTC](https://discourse.julialang.org/t/point-occlusion-in-3d-scatter-makie/95413/5 "2023-03-02T14:15:51Z")

</div>

Try the following little code. I have added an annotation that points to a specific example and this should be reproducible (although I’m not familiar with the details of seeding the RNG across julia versions/platforms. This was using Julia Version 1.8.5 on Windows).

```julia
using CairoMakie, Random

#Seed RNG
Random.seed!(21)

#Create Random Points
x = rand(1000)
y = rand(1000)
z = rand(1000)
	
#plot aligned along z-axis (higher Z is closer to camera)
fig = Figure()
ax1=Axis3(fig[1, 1], aspect=:data, azimuth = 0,elevation=2pi/4)
scatter!(x,y,z,color = z)

ax1.xlabel = "X"
ax1.ylabel = "Y"
ax1.zlabel = "Z"

#annotate a specific example
text!(1,0.95,1,text="←",color=:red,fontsize=24)
	
fig

```

This produces the below plot (in Pluto. Not sure how to pop up a plot viewer or save the figure from the REPL, I’m looking into it). It is a 3D scatter plot that where the camera is aligned with the z-axis. Higher Z is closer to the camera. Points are colored by Z position so we know that a lighter colored point is closer to the camera than a darker colored point. Nonetheless in this example (and indeed if you look a bit I can find several examples for any given seed) there is a darker colored point painted over the top of a lighter colored point.

 ![OcclusionAligned](https://global.discourse-cdn.com/julialang/original/3X/e/f/ef336fee598f9b1f082542235c27d11e317b505a.png)

---

<div class="post-metadata">

### Author: ![Salmon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/salmon/32/22968_2.png) [@Salmon](https://discourse.julialang.org/u/Salmon)
#### Post date: [March 2, 2023, 4:13pm UTC](https://discourse.julialang.org/t/point-occlusion-in-3d-scatter-makie/95413/6 "2023-03-02T16:13:30Z")

</div>

I believe this is a limitation of the Cairo backend:

> CairoMakie as a 2D engine has no concept of z-clipping, therefore its 3D capabilities are quite limited. The z-values of 3D plots will have no effect and will be projected flat onto the canvas. Z-layering is approximated by sorting all plot objects by their z translation value before drawing, after that by parent scene and then insertion order. Therefore, if you want to draw something on top of something else, but it ends up below, try translating it forward via `translate!(obj, 0, 0, some_positive_z_value)`.

[https://docs.makie.org/stable/documentation/backends/cairomakie/#z-order](https://docs.makie.org/stable/documentation/backends/cairomakie/#z-order)

I think for these occasions it is better to use GLMakie,  
which should be better capable of handling 3D plots.

---

<div class="post-metadata">

### Author: ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)
#### Post date: [March 2, 2023, 4:18pm UTC](https://discourse.julialang.org/t/point-occlusion-in-3d-scatter-makie/95413/7 "2023-03-02T16:18:12Z")

</div>

You could sort your points by z value, CairoMakie just draws them in original order currently

---

<div class="post-metadata">

### Author: ![Jordan\_Cluts](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jordan_cluts/32/13753_2.png) [@Jordan\_Cluts](https://discourse.julialang.org/u/Jordan_Cluts)
#### Post date: [March 2, 2023, 4:30pm UTC](https://discourse.julialang.org/t/point-occlusion-in-3d-scatter-makie/95413/8 "2023-03-02T16:30:16Z")

</div>

Ah interesting, I will give GLMakie a try to see if it fixes the issue.

---

<div class="post-metadata">

### Author: ![Jordan\_Cluts](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jordan_cluts/32/13753_2.png) [@Jordan\_Cluts](https://discourse.julialang.org/u/Jordan_Cluts)
#### Post date: [March 2, 2023, 4:31pm UTC](https://discourse.julialang.org/t/point-occlusion-in-3d-scatter-makie/95413/9 "2023-03-02T16:31:19Z")

</div>

In the toy example sorting by z value is pretty easy if it fixes the problem. In the general case where the camera is not aligned with an axis it would be a lot trickier (but not impossible I’m fairly certain).

---

<div class="post-metadata">

### Author: ![Salmon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/salmon/32/22968_2.png) [@Salmon](https://discourse.julialang.org/u/Salmon)
#### Post date: [March 2, 2023, 4:42pm UTC](https://discourse.julialang.org/t/point-occlusion-in-3d-scatter-makie/95413/10 "2023-03-02T16:42:11Z")

</div>

Well you’d have to specify the axis from which the plots perspective should be, but if you have it the z order should just be the value of the data points projection into the axis right?  
I.e.

```julia
axis = [1,1,1]
point = [x,y,z]
zorder = point'*axis

```

And so on.  
(Cannot try it out right now but this should do the trick)

---

<div class="post-metadata">

### Author: ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)
#### Post date: [March 2, 2023, 6:46pm UTC](https://discourse.julialang.org/t/point-occlusion-in-3d-scatter-makie/95413/11 "2023-03-02T18:46:10Z")

</div>

We could do it in the scatter render function, not sure why we’re not doing it. We’re doing it for meshes but not for other primitives.

---

<div class="post-metadata">

### Author: ![Jordan\_Cluts](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jordan_cluts/32/13753_2.png) [@Jordan\_Cluts](https://discourse.julialang.org/u/Jordan_Cluts)
#### Post date: [March 2, 2023, 6:59pm UTC](https://discourse.julialang.org/t/point-occlusion-in-3d-scatter-makie/95413/12 "2023-03-02T18:59:10Z")

</div>

I tried GLMakie which solved the occlusion issue but introduced other artifacts that I was unhappy with.

So I implemented the sort that you recommended taking advantage of `sortperm` and was able to get precisely what I wanted out of CairoMakie.

Here is the plot from my original post with the points sorted properly.

 ![CairoMakie_sorted](https://global.discourse-cdn.com/julialang/original/3X/7/5/75fb13e26ad8aba5cd24f9c6c5c942060d2b9bd5.png)

---

<div class="post-metadata">

### Author: ![grero](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/grero/32/109_2.png) [@grero](https://discourse.julialang.org/u/grero)
#### Post date: [November 28, 2023, 8:41am UTC](https://discourse.julialang.org/t/point-occlusion-in-3d-scatter-makie/95413/13 "2023-11-28T08:41:11Z")

</div>

Sorry for resurrecting this old(ish) thread, but I was trying to apply the solution to a plot consisting of multiple line, where each line is associated with some value that I want to sort the lines according to. The attached image shows what this looks like.  
The color of each line indicates the sorting, and I would like the dark blue lines to be in front, and the yellow lines at the back. However, the order appears to be jumbled up.  
I know I can achieve this in GLMakie, but the CairoMakie figure looks so much nicer.

I guess my question is what part of each line is used for determining the drawing order? I tried drawing the lines in the order dictated by the color, but that didn’t seem to help; the order was still scrambled. I also tried applying the z-order transform in the solution to OPs original question, but it wasn’t clear to me what point to use for each line.

 ![rtime_3d_plot](https://global.discourse-cdn.com/julialang/original/3X/7/6/763e0135cd0c010d6aeaa906742a6eebd121d7e2.png)

---

<div class="post-metadata">

### Author: ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)
#### Post date: [November 28, 2023, 3:30pm UTC](https://discourse.julialang.org/t/point-occlusion-in-3d-scatter-makie/95413/14 "2023-11-28T15:30:48Z")

</div>

CairoMakie sorts by z component of the transformation, not at all by data coordinates. So if you plot all the lines in back to front order it should look correct. Unless the sorting somehow doesn’t respect the original order if the transformation components are the same (0 if unset)

---

<div class="post-metadata">

### Author: ![grero](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/grero/32/109_2.png) [@grero](https://discourse.julialang.org/u/grero)
#### Post date: [November 28, 2023, 10:53pm UTC](https://discourse.julialang.org/t/point-occlusion-in-3d-scatter-makie/95413/15 "2023-11-28T22:53:03Z")

</div>

Thanks a lot, that worked. Somehow I had the impression that the lines should be plotted from front to back, which in hindsight doesn’t make sense. Plotting them back to front worked perfectly.
