Skip to content

Commit 266738b

Browse files
Austin MartinAustin Martin
authored andcommitted
fix(violin): prevent FP drift in KDE sampling loop (avoid underrun/overrun on tiny spans)
1 parent 361d8b5 commit 266738b

File tree

2 files changed

+16
-1
lines changed

2 files changed

+16
-1
lines changed

src/traces/violin/calc.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ module.exports = function calc(gd, trace) {
5050
var kde = helpers.makeKDE(cdi, trace, vals);
5151
cdi.density = new Array(n);
5252

53-
for(var k = 0, t = span[0]; t < (span[1] + step / 2); k++, t += step) {
53+
for(var k = 0; k < n; k++) {
54+
var t = span[0] + k * step;
5455
var v = kde(t);
5556
cdi.density[k] = {v: v, t: t};
5657
maxKDE = Math.max(maxKDE, v);

test/jasmine/tests/violin_test.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,20 @@ describe('Test violin calc:', function() {
401401
expect(cd.length).toBe(1, '# of violins');
402402
expect(cd[0].bandwidth).toBe(0, 'bandwidth');
403403
});
404+
405+
it('should produce exactly n density samples for tiny or near-equal spans', function() {
406+
var cd = _calc({
407+
type: 'violin',
408+
x: [0, 0],
409+
y: [0.5006312999999999, 0.5006313]
410+
});
411+
var cdi = cd[0];
412+
413+
var dist = cdi.span[1] - cdi.span[0];
414+
var n = Math.ceil(dist / (cdi.bandwidth / 3));
415+
416+
expect(cdi.density.length).toBe(n);
417+
});
404418
});
405419

406420
describe('Test violin hover:', function() {

0 commit comments

Comments
 (0)