Skip to content

fix: Pick the trace drawn last on a hover tie in scattergl and splom - #8079

Open
camdecoster wants to merge 5 commits into
mainfrom
cam/8077/hover-tie-scattergl
Open

camdecoster wants to merge 5 commits into
mainfrom
cam/8077/hover-tie-scattergl

Conversation

@camdecoster

@camdecoster camdecoster commented Sep 25, 2026 •

Copy link
Copy Markdown
Contributor

Description

Updates scattergl, splom logic to match scatter when a distance tie occurs during hover over a point.

Closes #8077.

Changes

  • Update scatter, splom hover check
  • Add tests
  • Update existing tests

Testing

  • Be on main
  • Open Plotly devtools and run the following snippet in the browser devtools console:
const gd = Tabs.fresh();
Plotly.newPlot(gd, {
    data: [
        { type: 'scattergl', name: 'A', mode: 'markers', marker: { size: 20, color: '#1f77b4' }, x: [0, 1, 2], y: [1, 0, 1] },
        { type: 'scattergl', name: 'B', mode: 'markers', marker: { size: 20, color: '#ff7f0e' }, x: [0, 1, 2], y: [2, 0, 2] }
    ],
    layout: {
        title: { text: 'scattergl: hover the shared point at (1, 0)' },
        width: 500,
        height: 400,
        hovermode: 'closest',
        xaxis: { range: [-0.5, 2.5] },
        yaxis: { range: [-0.5, 2.5] }
    }
});
  • Note that A shows up when hovering over the shared point
  • Switch to this branch
  • Run the snippet again
  • Note that B shows up now

Notes

  • This issue arose due to different tie breaking logic in scatter vs scattergl
  • There's an additional difference between the two methods, even with this change: scatter considers the size of the marker when determining the tie break but scattergl and splom don't
  • This means that on scatter, a marker that's beneath another but has a smaller radius can win the tie break. This is intentional so that users can still get feedback on the smaller marker when it's covered up. Try running this snippet to see what I'm talking about:
const gd = Tabs.fresh();
Plotly.newPlot(gd, {
    data: [
        { type: 'scatter', name: 'A', mode: 'markers', marker: { size: 5, color: '#1f77b4' }, x: [0, 1, 2], y: [1, 0, 1] },
        { type: 'scatter', name: 'B', mode: 'markers', marker: { size: 20, color: '#ff7f0e' }, x: [0, 1, 2], y: [2, 0, 2] }
    ],
    layout: {
        title: { text: 'scatter: hover the shared point at (1, 0)' },
        width: 500,
        height: 400,
        hovermode: 'closest',
        xaxis: { range: [-0.5, 2.5] },
        yaxis: { range: [-0.5, 2.5] }
    }
});
  • For now, scattergl and splom don't consider the radius. I deemed that to be out of scope for this PR, so I'll add a follow up issue to take care of it later.
  • This update required me to flip a loop for the scattergl hover logic when hovermode is something other than "x". In fix for ScatterGL hover and click events give the 'top' point instead of the 'bottom' point #3924, the loop was changed to run backward so that the highest index (the first) would win in the tie break. Due to the logic change, that no longer happened and tests started failing. Making the loop run forward fixes the issue while also maintaining the previous behavior.

@camdecoster
camdecoster marked this pull request as ready for review September 25, 2026 17:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG]: scatter and scattergl show different hover labels for overlapping data points

1 participant