I'm using Plotly to display an histogram with an hovertemplate displaying the value from the group. I need to display a precision to 3 digit, even when the data are big, however Plotly seems to round the value before that so with below example, hovertempalte jump from "28200.000 - 28500.000" to "28600.00 - 28800.00" and value 28589.02 is absorb by the second bar whereas it's below the min from the range.
Is there any option to change that precision on the %{x} value ? I tryed to use hoverformat: .3f
but it only add 0 to the end so it doesn't fix.
You can find the example here: https://stackblitz.com/edit/typescript-plotly-hfluqw?file=index.ts
const appDiv: HTMLElement = document.getElementById('app');
appDiv.innerHTML = `<div style="width: 100%; height: 100%" id="chart"></div>`;
import { newPlot } from 'plotly.js-dist';
const data = [
{
type: 'histogram',
marker: { color: 'red' },
mode: 'lines+markers',
x: [25000, 28333.952, 28334.08, 28589.02, 28945.89],
xbins: {
start: 25000,
end: 29340.479,
size: 394.589,
},
hovertemplate: 'value: %{x}',
},
];
const layout = {
bargap: 0.1,
hovermode: 'closest',
xaxis: {
hoverformat: ',.3f',
},
};
newPlot('chart', data, layout);
EDIT: fix the point within the range gap
I finally fix the biggest part of my issue by removing the start & end values from the xbins, leaving it to default from Plotly's logic. The displayed values are still rounded, so there is a jump, but the range always cover all points, so in above example the ranges were fixed to "28.1k - 28.4k" and "28.5k - 28.7k". I think the start and end were shifting this and broke some Plotly rounding logic.
Unfortunately, it seems that currently this is expected behavior, and that's just how Plotly internal bin range "shrinkage" works.
There's an open Github issue asking a similar, more simple question: How come a bin size of 50 displays ranges of 0-40
, 50-90
, etc, as shown in this live demo?
A developer explains:
This is all in service of greater clarity at the bin edges. To be precise, what's happening here is two things:
- We detected that the data values are all integers, so we shifted the bin edges down 0.5 to ensure that NO values are exactly at a bin edge. You can see this if you zoom in, the bins actually go -0.5 -> 49.5, 49.5 -> 99.5, 99.5 -> 149.5 etc
- But listing exactly those values in the hover label would be confusing: what are half-integer values doing in a label for integer data? So we look at the data again and ask: what's the closest any value gets to the left or right edge of a bin? In this case it's 0.5 from the left edge and 9.5 from the right, and based on the bin width of 50 we can always represent these values with a zero at the end, so that's what we do - 0-40, 50-90, 100-140 etc. If you add a value that's just a little closer to the right edge of a bin - say change one of the 140s to 141 - you'll see the labels change to 0-49, 50-99, 100-149 etc, since we can no longer round to a bigger digit.
What we really DON'T want to do is have labels 50-100 and 100-150, because then it's ambiguous in which bin we put a value of exactly 100. But you could perhaps argue that the bin shift should match the range shrinkage - ie because we shifted the bins exactly 0.5 here we should also shrink the ranges we report by exactly 0.5 on each side, to 50-99, or if we want to keep 50-90 we should shift the bins by 5.
This explanation applies for your case as well: If you'll try to add the value 28551
, which is exactly at the right edge of the 8th bin\left edge of the 9th bin (because: 25000 + (394.589 * 9) = 28551.301
), you'll notice that the hovered bin edges becomes very precise - as you can see here.
So it seems that there's not much to do about it, at least for now.