You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[BUG]: axis.layer / axis.zerolinelayer: 'above traces' do not render above scattergl traces #8075
Parent: layout.xaxis
Type: enumerated , one of ( "above traces" | "below traces" )
Default: "above traces"
Sets the layer on which this axis is displayed. If "above traces", this axis is displayed above all the subplot's traces If "below traces", this axis is displayed below all the subplot's traces, but above the grid lines. Useful when used together with scatter-like traces with cliponaxis set to "false" to show markers and/or text nodes above this axis.
Parent: layout.xaxis
Type: enumerated , one of ( "above traces" | "below traces" )
Default: "below traces"
Sets the layer on which this zeroline is displayed. If "above traces", this zeroline is displayed above all the subplot's traces If "below traces", this zeroline is displayed below all the subplot's traces, but above the grid lines. Limitation: "zerolinelayer" currently has no effect if the "zorder" property is set on any trace.
However, this does not work for scattergl.
A WebGL marker remains visually above the zeroline (y = 0) even when:
I looked at the cause. All WebGL traces draw into one full-size canvas in .gl-container. That container sits between the first main-svg and the top main-svg (makePlotFramework in src/plot_api/plot_api.js). The cartesian "above" layers (zerolinelayer-above, xlines-above, xaxislayer-above) are in the subplot group inside the first main-svg (makeSubplotLayer in src/plots/cartesian/index.js). Thus the WebGL canvas always paints above them, and layer / zerolinelayer only change the order relative to SVG traces. Image export keeps the same order.
I see two directions:
For subplots with WebGL traces, draw the "above" axis layers in the top main-svg, as parcoords does for its axes. This changes the paint order relative to inset subplots and zorder, and many gl2d baselines will move.
Add the limitation to the layer and zerolinelayer descriptions, next to the existing zorder note.
Which direction do you prefer? If you pick one, I can open a PR for it.
No, I haven’t run into this bug in my own work. I was looking for open bugs I could help fix, and the reproduction for this one looked clearer to me.
I don’t have a use case that needs option 1. If changing the paint order and the test baselines isn’t worth it without such a need, I can open a PR for option 2 (documenting the limitation next to the zorder note).
Actually, I would pick option 1, because it fixes the bug. Also, I work a lot with charts and data visualization in my job, and honestly, solving a problem like this would teach me something.
In short: all WebGL traces sit in one canvas, and this canvas stays above the axes. The bug comes exactly from this. The fix is to move the parts of the axes that are set to "above" into the SVG above the canvas. I would do this only for WebGL plots, because if I did it for all plots, in regular plots the axes of the big plot would go above the small plot inside it.
Activity
camdecoster commentedon Sep 28, 2026
You're great at finding these implementation bugs! I'll add this one to our backlog as well. If you feel like fixing it, let us know.
piupiunn commentedon Oct 26, 2026
I looked at the cause. All WebGL traces draw into one full-size canvas in
.gl-container. That container sits between the firstmain-svgand the topmain-svg(makePlotFrameworkinsrc/plot_api/plot_api.js). The cartesian "above" layers (zerolinelayer-above,xlines-above,xaxislayer-above) are in the subplot group inside the firstmain-svg(makeSubplotLayerinsrc/plots/cartesian/index.js). Thus the WebGL canvas always paints above them, andlayer/zerolinelayeronly change the order relative to SVG traces. Image export keeps the same order.I see two directions:
main-svg, as parcoords does for its axes. This changes the paint order relative to inset subplots andzorder, and many gl2d baselines will move.layerandzerolinelayerdescriptions, next to the existingzordernote.Which direction do you prefer? If you pick one, I can open a PR for it.
camdecoster commentedon Oct 27, 2026
Have you encountered this bug? How would fixing it help you with your work?
piupiunn commentedon Oct 27, 2026
No, I haven’t run into this bug in my own work. I was looking for open bugs I could help fix, and the reproduction for this one looked clearer to me.
I don’t have a use case that needs option 1. If changing the paint order and the test baselines isn’t worth it without such a need, I can open a PR for option 2 (documenting the limitation next to the zorder note).
camdecoster commentedon Oct 29, 2026
Thanks for investigating. Which solution do you prefer?
piupiunn commentedon Oct 29, 2026
Actually, I would pick option 1, because it fixes the bug. Also, I work a lot with charts and data visualization in my job, and honestly, solving a problem like this would teach me something.
In short: all WebGL traces sit in one canvas, and this canvas stays above the axes. The bug comes exactly from this. The fix is to move the parts of the axes that are set to "above" into the SVG above the canvas. I would do this only for WebGL plots, because if I did it for all plots, in regular plots the axes of the big plot would go above the small plot inside it.
Is this OK with you? If yes, I will open a PR.