Skip to content

Commit 12a0ab6

Browse files
committed
violin: defaults to zero width if span is zero
1 parent 121db9c commit 12a0ab6

File tree

5 files changed

+34
-24
lines changed

5 files changed

+34
-24
lines changed

src/traces/violin/calc.js

+29-20
Original file line numberDiff line numberDiff line change
@@ -37,24 +37,32 @@ module.exports = function calc(gd, trace) {
3737
var bandwidth = cdi.bandwidth = calcBandwidth(trace, cdi, vals);
3838
var span = cdi.span = calcSpan(trace, cdi, valAxis, bandwidth);
3939

40-
// step that well covers the bandwidth and is multiple of span distance
41-
var dist = span[1] - span[0];
42-
var n = Math.ceil(dist / (bandwidth / 3));
43-
var step = dist / n;
44-
45-
if(!isFinite(step) || !isFinite(n)) {
46-
Lib.error('Something went wrong with computing the violin span');
47-
cd[0].t.empty = true;
48-
return cd;
49-
}
50-
51-
var kde = helpers.makeKDE(cdi, trace, vals);
52-
cdi.density = new Array(n);
53-
54-
for(var k = 0, t = span[0]; t < (span[1] + step / 2); k++, t += step) {
55-
var v = kde(t);
56-
cdi.density[k] = {v: v, t: t};
57-
maxKDE = Math.max(maxKDE, v);
40+
if(cdi.min === cdi.max && bandwidth === 0) {
41+
// if span is zero and bandwidth is zero, we want a violin with zero width
42+
span = cdi.span = [cdi.min, cdi.max];
43+
cdi.density = [{v: 1, t: span[0]}];
44+
cdi.bandwidth = bandwidth;
45+
maxKDE = Math.max(maxKDE, 1);
46+
} else {
47+
// step that well covers the bandwidth and is multiple of span distance
48+
var dist = span[1] - span[0];
49+
var n = Math.ceil(dist / (bandwidth / 3));
50+
var step = dist / n;
51+
52+
if(!isFinite(step) || !isFinite(n)) {
53+
Lib.error('Something went wrong with computing the violin span');
54+
cd[0].t.empty = true;
55+
return cd;
56+
}
57+
58+
var kde = helpers.makeKDE(cdi, trace, vals);
59+
cdi.density = new Array(n);
60+
61+
for(var k = 0, t = span[0]; t < (span[1] + step / 2); k++, t += step) {
62+
var v = kde(t);
63+
cdi.density[k] = {v: v, t: t};
64+
maxKDE = Math.max(maxKDE, v);
65+
}
5866
}
5967

6068
maxCount = Math.max(maxCount, vals.length);
@@ -105,8 +113,9 @@ function calcBandwidth(trace, cdi, vals) {
105113
if(trace.bandwidth) {
106114
return trace.bandwidth;
107115
} else {
108-
// plot single-value violin with bandwidth of 1
109-
return 1;
116+
// if span is zero and no bandwidth is specified
117+
// it returns zero bandwidth which is a special case
118+
return 0;
110119
}
111120
}
112121

-1.35 KB
Loading

test/image/mocks/violin-offsetgroups.json

+3
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@
6666
}
6767
],
6868
"layout": {
69+
"template": {
70+
"data": {"violin": [{"bandwidth": 1}]}
71+
},
6972
"violinmode": "group",
7073
"showlegend": false,
7174
"grid": {

test/image/mocks/violin_only_zeroes.json

-2
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,13 @@
44
"y": [0, 0, 0, 0],
55
"points": "all",
66
"pointpos": 0,
7-
"bandwidth": 0.025,
87
"meanline": {
98
"visible": true
109
}
1110
}, {
1211
"type": "violin",
1312
"y": [2, 2, 2, 2],
1413
"points": "all",
15-
"bandwidth": 0.1,
1614
"pointpos": 0
1715
}, {
1816
"type": "violin",

test/jasmine/tests/violin_test.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ describe('Test violin calc:', function() {
280280
});
281281

282282
expect(cd.length).toBe(6, '# of violins');
283-
expect(cd.every(function(d) { return d.bandwidth; })).toBe(true, 'bandwidth');
283+
expect(cd.every(function(d) { return d.bandwidth; })).toBe(false, 'bandwidth');
284284
});
285285

286286
it('handle multi-value / single-but-unique-value case', function() {
@@ -289,7 +289,7 @@ describe('Test violin calc:', function() {
289289
});
290290

291291
expect(cd.length).toBe(1, '# of violins');
292-
expect(cd[0].bandwidth).toBe(1, 'bandwidth');
292+
expect(cd[0].bandwidth).toBe(0, 'bandwidth');
293293
});
294294
});
295295

0 commit comments

Comments
 (0)