Skip to content

fix: snap tick values to grid before applying custom tickformat#7810

Open
arieleli01212 wants to merge 1 commit into
plotly:masterfrom
arieleli01212:fix-tickformat-fp-artefacts
Open

fix: snap tick values to grid before applying custom tickformat#7810
arieleli01212 wants to merge 1 commit into
plotly:masterfrom
arieleli01212:fix-tickformat-fp-artefacts

Conversation

@arieleli01212
Copy link
Copy Markdown

Fixes #7765

What's wrong

When floating-point arithmetic leaves a tick value slightly off its true grid position — for example -8.88e-16 instead of 0 — the result depends on which formatter is used. The built-in formatter is safe because it adds an internal rounding epsilon and then rounds to the computed number of significant digits. But when a user sets tickformat (e.g. '~r', '.4f') the value is passed straight to d3-format, which faithfully renders the raw float:

−0.0000000000000000888178   ← tick that should be 0, rendered with tickformat: '~r'

The fix

Before delegating to the user's formatter, snap v to the nearest ideal tick position tick0 + n * dtick. The tolerance is 1e-9 × dtick, which is well below any deliberate non-zero tick value but comfortably above the floating-point noise that accumulates over a handful of dtick additions.

The snap is only applied to non-hover labels (hover already independently recalculates its own rounding) and only when both tick0 and dtick are numeric (so date and log axes are unaffected).

Changes

  • src/plots/cartesian/axes.js — snap inside numFormat before the tickformat early-return
  • test/jasmine/tests/axes_test.js — two cases: dtick: 0.5 (the exact scenario from the issue) and dtick: 0.1 (a dtick that itself accumulates FP error over several steps)

When floating-point arithmetic produces a tick value that is slightly
off its true position (e.g. -8.88e-16 instead of 0), the default
formatter is immune because it adds an internal rounding epsilon before
rendering. Custom d3 formats specified via tickformat (such as '~r')
don't go through that path and expose the raw number, which can produce
labels like '−0.0000000000000000888178' for a tick that should read '0'.

Fix by snapping v to the nearest ideal tick position (tick0 + n*dtick)
before passing it to the user's formatter, using a relative threshold
of 1e-9 of dtick so only genuine floating-point noise is removed.

Fixes plotly#7765
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

1 participant