Skip to content

[BUG]: axis.layer / axis.zerolinelayer: 'above traces' do not render above scattergl traces #8075

Open

Description

@Lexachoc

Description:

For Cartesian axes/subplots (for example, those containing scatter traces),
the reference documentation states that:

layer

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.

zerolinelayer

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:

yaxis: {
  zerolinelayer: 'above traces'
}

is set.

Reproducible example:

https://codepen.io/Lexachoc/pen/xbqdWqm

https://codepen.io/Lexachoc/pen/EaWmLKY (line chart)


Relationship to cliponaxis:

This is separate from the feature request in #8074.

cliponaxis controls whether markers/text are clipped to the subplot's plotting area.

axis.layer / axis.zerolinelayer, on the other hand, control the stacking order of the axis / zeroline relative to traces.

Effect of axis.layer / axis.zerolinelayer: 'above traces':
Image

Effect of axis.layer / axis.zerolinelayer: 'above traces' for line chart (the red line should not be seen):

Image

Effect of cliponaxis: false:
Image

Activity

  1. camdecoster commented on Sep 28, 2026

    @camdecoster
    Contributor

    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.

  2. piupiunn commented on Oct 26, 2026

    @piupiunn

    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:

    1. 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.
    2. 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.

  3. camdecoster commented on Oct 27, 2026

    @camdecoster
    Contributor

    Have you encountered this bug? How would fixing it help you with your work?

  4. piupiunn commented on Oct 27, 2026

    @piupiunn

    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).

  5. camdecoster commented on Oct 29, 2026

    @camdecoster
    Contributor

    Thanks for investigating. Which solution do you prefer?

  6. piupiunn commented on Oct 29, 2026

    @piupiunn

    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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions