CairoMakie get 3d plots to respect z order

I’m trying to export figure as a PDF using CairoMakie. Some of my subplots are 3d axes. I’m plotting several surfaces that wrap around each other, so some parts of surface A are behind surface B and some parts are in front. I’m looking for any way of exporting my whole figure as a vectorised pdf using CairoMakie but somehow keeping the 3d plots correct.

For some reason I thought rasterizing the plot objects might help, and I thought there might be a way to “rasterize multiple plot elements together”. Is that possible? Is there any workaround? And I take it there’s definitely no workaround to get vectorised 3d plots working?

edit: They don’t need to be surfaces, lines would be fine. I just checked with MATLAB, and after importing a .pdf from matlab into inkscape it seems like they split their line object up into lots of small lines so different parts of line A can be infront/behind different parts of line B? If I wanted to implement this can I just loop over all the lines in my axis, split every line up into N lines, calculate each sub-line’s distance from the camera and then replot all the lines in the correct order? Is that all it would take to get vectorised lines in a 3d axis or am I missing something?

edit2: I did the above and it seems to work well so far. apologies for making a post without trying a bit harder…

1 Like

Maybe this helps? CairoMakie z-order

Surfaces won’t work in vector graphics unless you manually computed their intersections and resolved the depth order. Sounds pretty complicated. One alternative with rasterization would be to use GLMakie and then copy the rasterized part over via the colorbuffer function.

For now I’ve written some code that splits all the lines and surfaces in an Axis up into sub-lines and sub-surfaces and replots them all in the correct order. This works quite well for simple cases

But for more complex surfaces (and my actual use case) there are some small lines where the sub-surfaces meet which I can’t quite figure how to get rid of

which doesn’t really matter I suppose, and by rasterizing every sub-surface the file sizes aren’t too large.

I might look into colorbuffer if I decide that the small artefacts where surfaces meet is too annoying, thanks for pointing that out!

This is slightly tangentially related but I wanted to point out that I tackled a related issue about a year ago but with scatter. I eventually solved the problem using guidance from others here by sorting my points from furthest to closest to the camera. Maybe some details there will be useful to you.

Hi thanks for your reply, definitely very related! This is basically what I did after splitting up lines and surfaces into sub-lines and sub-surfaces. I then sort the sub-lines and sub-surfaces based on distance from the camera

In case it’s useful for anyone else, here is the code I’m using. Package exports replot_lines!(ax,Nlines) and replot_surfaces!(ax,Nx,Ny,sub_surface_Nx,sub_surface_Ny). How well it works requires tuning Nlines which is how many lines to split the lines into, and Nx,Ny,sub_surface_Nx,sub_surface_Ny, which are parameters for how many points to split up the original surface into and how many points to calculate for the sub-surfaces.

I expect it won’t work for lots of cases, but works okay for me!

1 Like