With Algebra of Graphics + Makie, how do I control the z-order of plots, i.e. which plot goes on top of which?

Take this examples for the AoG documentation: Example gallery · Algebra of Graphics
Here, green is on top of orange is on top of blue. Say I wanted to reverse the order, i.e. have blue on top, how would I do that?

I tried using a sorter in the mapping but, while it changes the order of the legend entries appropriately, it doesn’t seem to effect the z-order of the plots.

Interesting that sorting doesn’t affect the drawing order in AlgebraOfGraphics, I would have thought it does.

GLMakie and WGLMakie are real 3D engines, so there the order is decided with the z-buffer, or the insertion order for ties. In CairoMakie, there is no z-buffer, only drawing order. I’ve made it so that plot objects are sorted by insertion order and by the z coordinate of their transformation. For many scenarios, that gives the same apparent result as in GLMakie. So you could theoretically do translate!(density_plot_object, 0, 0, 1) to shift one density plot a bit forward. One example for that is here density

There was an “optimization” that scrambled the plotting order, should be addressed by this PR (docs preview here). This way the “z-order” should follow the sorting order (smaller values get drawn first and appear first in the legend). This is the same as one would get by doing the plot directly in Makie, so it should be a reasonable default. Could you check out the PR and see if it fixes your usecase?

For more nuanced situations (say one wants to order plots and legend differently, or more complex z orderings), I’m not sure what’s the best solution. Maybe adding an explicit z_order attribute to Makie? I imagine it would be easy to implement given that a similar machinery exists for z coordinates. OTOH, just using z coordinates doesn’t work in general for e.g. contours and more complex plots.

CairoMakie looks only at the z transform, not individual scatter marks etc. Maybe for scatters that could be done, as each marker has one z, but it fails already with lines. Also, it makes the drawing code very complex, if we jump around from plot object to plot object.