Skip to content

Fix floating-point artefacts in tick labels (snap near-zero ticks to tick0)#7901

Merged
camdecoster merged 4 commits into
plotly:masterfrom
kirthi-b:fix/tick-label-float-artefacts
Jul 13, 2026
Merged

Fix floating-point artefacts in tick labels (snap near-zero ticks to tick0)#7901
camdecoster merged 4 commits into
plotly:masterfrom
kirthi-b:fix/tick-label-float-artefacts

Conversation

@kirthi-b

Copy link
Copy Markdown
Contributor

What this fixes

Tick labels could show values like -0.0000000000000000888178 where the tick should read 0. Reported in #7765.

Why it happens

calcTicks builds tick values by repeated increments. With an unspecified tick0 (so it defaults to 0), a tick that should sit exactly on 0 can come out as a tiny nonzero value such as -8.9e-17 due to floating-point roundoff. The default numeric formatter rounds that away, but d3-format specs like ~r pass the value straight through and print it in full.

The change

In calcTicks, when a computed tick value is far closer to tick0 than one dtick (within dtick times 1e-6), snap it to exactly tick0. This matches the narrow fix alexcjohnson outlined in the issue: with a default tick0 of 0 it is unambiguous that such a tick belongs at zero. It is limited to linear axes and numeric dtick, so date, log, and category axes are untouched.

Known limitation, same one noted in the issue: this snaps to tick0, so it does not cover the case where someone sets a nonzero tick0 but a tick still falls on zero (for example tick0=1, dtick=0.1). That would need a separate heuristic and is left out to keep this change small.

Test

Added a jasmine test in axes_test.js that builds the reproducing range ([-0.65, 0.65], tick0 0, dtick 0.2) and checks that with tickformat ~r the zero tick renders as "0" rather than the artefact, and that the default format stays correct. Verified it fails without the source change and passes with it.

Thanks to camdecoster for offering to prioritize review of a PR for this.

Fixes #7765

kirthi-b and others added 4 commits July 12, 2026 16:37
When ticks are built by repeated increments, a tick that should sit
exactly on tick0 can come out as a tiny nonzero value like -8.9e-17.
The default numeric format rounds that away, but d3-format specs such as
`~r` render it literally, so a tick at zero showed as
-0.0000000000000000888178. When a computed tick value is far closer to
tick0 than one dtick, snap it to exactly tick0.

Fixes plotly#7765

@camdecoster camdecoster left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR! You're actually the third person to submit a PR for this issue, so I guess it's time I actually followed through on the review. Your initial solution to snap to tick0 was a good idea, but I decided to generalize it more to allow for snapping to a multiple of the tick delta (which is what the user that wrote #7810 was doing). I also added another test for a non-snap-to-zero case. Collaboration all around! Once CI passes I'll get this merged.

@camdecoster camdecoster merged commit a677f28 into plotly:master Jul 13, 2026
84 of 85 checks passed
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]: floating-point artefacts in tick labels

2 participants