From 9329a4dd5e8065626710d8e6d311ef8997c1d9a7 Mon Sep 17 00:00:00 2001 From: jgould Date: Thu, 12 Apr 2018 12:11:11 -0400 Subject: [PATCH 1/5] use supplied bandwidth if provided --- src/traces/violin/calc.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/traces/violin/calc.js b/src/traces/violin/calc.js index 2311e7c4b16..d4dc7d11328 100644 --- a/src/traces/violin/calc.js +++ b/src/traces/violin/calc.js @@ -42,13 +42,12 @@ module.exports = function calc(gd, trace) { // sample standard deviation var ssd = Lib.stdev(vals, len - 1, cdi.mean); - var bandwidthDflt = ruleOfThumbBandwidth(vals, ssd, cdi.q3 - cdi.q1); - var bandwidth = cdi.bandwidth = trace.bandwidth || bandwidthDflt; + var bandwidth = cdi.bandwidth = trace.bandwidth || ruleOfThumbBandwidth(vals, ssd, cdi.q3 - cdi.q1); var span = cdi.span = calcSpan(trace, cdi, valAxis, bandwidth); // step that well covers the bandwidth and is multiple of span distance var dist = span[1] - span[0]; - var n = Math.ceil(dist / (Math.min(bandwidthDflt, bandwidth) / 3)); + var n = Math.ceil(dist / (bandwidth / 3)); var step = dist / n; if(!isFinite(step) || !isFinite(n)) { From 6e9244bf6576bb0ed983adbd74c3dfb65ffa3991 Mon Sep 17 00:00:00 2001 From: etienne Date: Tue, 22 May 2018 15:10:57 -0400 Subject: [PATCH 2/5] use Scott's rule to compute the dflt bandwidth ... when Silverman's rule give too small of a results --- src/traces/violin/calc.js | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/src/traces/violin/calc.js b/src/traces/violin/calc.js index d4dc7d11328..5fd590f6195 100644 --- a/src/traces/violin/calc.js +++ b/src/traces/violin/calc.js @@ -38,11 +38,8 @@ module.exports = function calc(gd, trace) { for(var i = 0; i < cd.length; i++) { var cdi = cd[i]; var vals = cdi.pts.map(helpers.extractVal); - var len = vals.length; - // sample standard deviation - var ssd = Lib.stdev(vals, len - 1, cdi.mean); - var bandwidth = cdi.bandwidth = trace.bandwidth || ruleOfThumbBandwidth(vals, ssd, cdi.q3 - cdi.q1); + var bandwidth = cdi.bandwidth = calcBandwidth(trace, cdi, vals); var span = cdi.span = calcSpan(trace, cdi, valAxis, bandwidth); // step that well covers the bandwidth and is multiple of span distance @@ -74,13 +71,30 @@ module.exports = function calc(gd, trace) { return cd; }; -// Default to Silveman's rule of thumb: +// Default to Silveman's rule of thumb, but if 'too small' use Scott's rule // - https://stats.stackexchange.com/a/6671 // - https://en.wikipedia.org/wiki/Kernel_density_estimation#A_rule-of-thumb_bandwidth_estimator // - https://github.com/statsmodels/statsmodels/blob/master/statsmodels/nonparametric/bandwidths.py -function ruleOfThumbBandwidth(vals, ssd, iqr) { +function silvermanRule(len, ssd, iqr) { var a = Math.min(ssd, iqr / 1.349); - return 1.059 * a * Math.pow(vals.length, -0.2); + return 1.059 * a * Math.pow(len, -0.2); +} + +function scottRule(len, ssd) { + return ssd * Math.pow(len, -0.2); +} + +function calcBandwidth(trace, cdi, vals) { + if(trace.bandwidth) return trace.bandwidth; + + var len = vals.length; + var ssd = Lib.stdev(vals, len - 1, cdi.mean); + var bw = silvermanRule(len, ssd, cdi.q3 - cdi.q1); + + if((cdi.max - cdi.min) / bw > 1e5) { + bw = scottRule(len, ssd); + } + return bw; } function calcSpan(trace, cdi, valAxis, bandwidth) { From 0661af3f64457c3ce61707b5fd5c9e392c2b7b38 Mon Sep 17 00:00:00 2001 From: etienne Date: Tue, 22 May 2018 15:11:26 -0400 Subject: [PATCH 3/5] add mock for scott rule + custom bandwidth --- test/image/baselines/violin_scott-rule.png | Bin 0 -> 20338 bytes test/image/mocks/violin_scott-rule.json | 458 +++++++++++++++++++++ 2 files changed, 458 insertions(+) create mode 100644 test/image/baselines/violin_scott-rule.png create mode 100644 test/image/mocks/violin_scott-rule.json diff --git a/test/image/baselines/violin_scott-rule.png b/test/image/baselines/violin_scott-rule.png new file mode 100644 index 0000000000000000000000000000000000000000..994dc1182ed174f083e24dfd223b4b1a4d02eacb GIT binary patch literal 20338 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 S;BV=X+`g%Oqfqr>$o~RJoeyXL literal 0 HcmV?d00001 diff --git a/test/image/mocks/violin_scott-rule.json b/test/image/mocks/violin_scott-rule.json new file mode 100644 index 00000000000..a06692896d3 --- /dev/null +++ b/test/image/mocks/violin_scott-rule.json @@ -0,0 +1,458 @@ +{ + "data": [ + { + "name": "with scott rule bandwidth", + "type": "violin", + "points": false, + "y": [ + 2.4403208885500003e-7, + 6.624100740240001e-8, + 8.164963286729999e-8, + 0.00000550607937631, + 3.02033017347e-8, + 3.7801716937800004e-7, + 5.56297659998e-8, + 5.406555702509999e-8, + 3.31213740697e-8, + 1.0835987313399999e-7, + 3.19669534548e-7, + 2.8017014902900004e-8, + 2.4514782933900002e-8, + 5.95554346643e-7, + 4.70654584492e-8, + 2.3361313822699997e-11, + 3.06469187871e-7, + 2.07771831308e-8, + 5.04663715295e-8, + 5.67592023418e-8, + 6.719484075659999e-8, + 2.3359219312100003e-9, + 7.32680903665e-8, + 1.56153538012e-7, + 5.92551838794e-8, + 6.48377885533e-8, + 6.5098659424e-8, + 1.92267340995e-7, + 6.27042106128e-10, + 3.79763712636e-8, + 5.79353363587e-8, + 2.01568499962e-7, + 4.5710354583899996e-8, + 8.68326386359e-8, + 2.00314121449e-7, + 4.16735959037e-11, + 1.05264632654e-7, + 1.3219377534799998e-8, + 1.1323983991099999e-7, + 7.9066491519e-9, + 3.29907596399e-7, + 3.58952178646e-7, + 3.06223788373e-8, + 1.34570962274e-7, + 1.95650463375e-7, + 8.88142553786e-8, + 6.33259714546e-7, + 7.89150230354e-8, + 3.44378121049e-8, + 3.56491902649e-8, + 7.17020398538e-8, + 0.00000117543109624, + 1.31723026752e-7, + 6.15562220021e-7, + 1.0411983170000001e-8, + 6.35306917979e-8, + 1.4244199622e-7, + 5.50507070561e-8, + 4.11937918362e-7, + 1.1436582759e-7, + 9.00381861905e-8, + 3.5761650960999997e-7, + 5.406555702509999e-8, + 1.91340425062e-8, + 4.05244277276e-8, + 1.67071698044e-8, + 2.64702379432e-7, + 4.54083719121e-8, + 1.15367276299e-8, + 7.01160189225e-8, + 2.12020626256e-7, + 7.55952714792e-8, + 3.35252445825e-8, + 6.410902643609999e-8, + 7.822972433139998e-8, + 3.00394443348e-8, + 1.85872035552e-7, + 3.21694096675e-8, + 1.9166603712099998e-8, + 1.4382528776500002e-7, + 2.30600946296e-7, + 1.1977210552999998e-7, + 3.21694096675e-8, + 3.1720115986e-7, + 5.00989110573e-12, + 2.14001834758e-9, + 3.57324647064e-7, + 9.836368168600001e-8, + 1.3317117896700002e-8, + 6.624100740240001e-8, + 3.0650079256e-8, + 3.23881793333e-8, + 0.0000010477687171799999, + 2.47766478953e-8, + 4.00638166198e-7, + 3.7385796368e-8, + 0.00000110210670495, + 5.16171069606e-9, + 5.5306060294599996e-8, + 7.43346458468e-8, + 2.98025726842e-8, + 4.50223643894e-8, + 2.6869636474599998e-11, + 2.23102995275e-7, + 6.624100740240001e-8, + 8.837339991869999e-8, + 1.0959679528299999e-7, + 7.70759415991e-8, + 9.19332979062e-8, + 5.72570744297e-9, + 5.67957997273e-12, + 7.200621520489999e-8, + 8.75570719476e-8, + 1.38879577383e-7, + 5.8323354775900006e-8, + 8.46519385822e-8, + 0.0000010404658225700002, + 2.7344550343299998e-8, + 1.1561451197599999e-7, + 3.37647982763e-7, + 1.03142857372e-7, + 3.0261981891400004e-8, + 1.0770523872e-7, + 5.56297659998e-8, + 4.45345220689e-7, + 5.190799176779999e-7, + 1.1878461076600001e-7, + 6.37944980645e-8, + 1.028044903e-7, + 2.35063847817e-8, + 3.35252445825e-8, + 1.75860650771e-7, + 5.95322200005e-8, + 2.3051930735100003e-7, + 1.01713704525e-7, + 6.36298925611e-8, + 8.32962182234e-9, + 1.73171410467e-7, + 5.92070463445e-8, + 1.35192178624e-7, + 1.80208181383e-7, + 2.32965100186e-7, + 5.558425986229999e-7, + 1.64668938007e-7, + 6.01836809013e-8, + 1.9915955477200002e-16, + 9.96792751761e-9, + 1.63404871286e-9, + 2.64702379432e-7, + 7.55162232084e-8, + 5.49833977189e-8, + 3.4953095347400004e-8, + 2.21025674493e-8, + 1.01029071417e-7, + 2.30733613826e-7, + 8.50266378712e-8, + 3.492997660290001e-8, + 1.72122175426e-7, + 6.06902637292e-8, + 2.0951701376400003e-8, + 5.13108366946e-7, + 2.80764979683e-7, + 7.49786710527e-7, + 1.28767098858e-7, + 0.00000130482668731, + 2.94524334014e-8, + 1.0383202068400001e-7, + 1.06529852732e-7, + 3.06223788373e-8, + 6.666061263539999e-8, + 2.77669768835e-7, + 1.9614212065399998e-7, + 7.57552863852e-9, + 1.3646260448700003e-8, + 1.55911616248e-8, + 4.2985875019e-8, + 5.35662859053e-7, + 1.31723026752e-7, + 2.8589493252999997e-8, + 6.15562220021e-7, + 2.48257838284e-8, + 5.54992004418e-8, + 1.59590984401e-7, + 1.05027747717e-7, + 4.16404749061e-15, + 3.21694096675e-8, + 1.55235536247e-8, + 7.22158660254e-8, + 7.3548078204e-11, + 5.12189467799e-8, + 5.78423562453e-7, + 7.34977455259e-8, + 8.428837152339999e-8, + 5.41683911418e-8, + 2.0892157394300002e-7, + 8.45875572871e-8, + 3.19669534548e-7, + 2.4721993929599997e-8, + 1.97866536768e-7, + 3.1078269037e-8, + 4.7958877370199995e-8, + 1.63190113114e-8, + 1.55306103512e-7, + 6.20692035531e-7, + 3.82587877803e-7, + 3.3292850458999995e-12, + 6.62976422611e-11, + 0.363112695543, + 1.2438406655e-7, + 1.57716890468e-7, + 8.270934005960001e-8, + 7.7356150975e-8, + 4.17240969082e-7, + 1.5340551258000003e-8, + 7.2558862077e-7, + 8.628154354439999e-8, + 0.00000130967390314, + 5.63969380635e-8 + ] + }, + { + "bandwidth": 0.03364359551927969, + "name": "with custom bandwidth", + "type": "violin", + "points": false, + "y": [ + 2.4403208885500003e-7, + 6.624100740240001e-8, + 8.164963286729999e-8, + 0.00000550607937631, + 3.02033017347e-8, + 3.7801716937800004e-7, + 5.56297659998e-8, + 5.406555702509999e-8, + 3.31213740697e-8, + 1.0835987313399999e-7, + 3.19669534548e-7, + 2.8017014902900004e-8, + 2.4514782933900002e-8, + 5.95554346643e-7, + 4.70654584492e-8, + 2.3361313822699997e-11, + 3.06469187871e-7, + 2.07771831308e-8, + 5.04663715295e-8, + 5.67592023418e-8, + 6.719484075659999e-8, + 2.3359219312100003e-9, + 7.32680903665e-8, + 1.56153538012e-7, + 5.92551838794e-8, + 6.48377885533e-8, + 6.5098659424e-8, + 1.92267340995e-7, + 6.27042106128e-10, + 3.79763712636e-8, + 5.79353363587e-8, + 2.01568499962e-7, + 4.5710354583899996e-8, + 8.68326386359e-8, + 2.00314121449e-7, + 4.16735959037e-11, + 1.05264632654e-7, + 1.3219377534799998e-8, + 1.1323983991099999e-7, + 7.9066491519e-9, + 3.29907596399e-7, + 3.58952178646e-7, + 3.06223788373e-8, + 1.34570962274e-7, + 1.95650463375e-7, + 8.88142553786e-8, + 6.33259714546e-7, + 7.89150230354e-8, + 3.44378121049e-8, + 3.56491902649e-8, + 7.17020398538e-8, + 0.00000117543109624, + 1.31723026752e-7, + 6.15562220021e-7, + 1.0411983170000001e-8, + 6.35306917979e-8, + 1.4244199622e-7, + 5.50507070561e-8, + 4.11937918362e-7, + 1.1436582759e-7, + 9.00381861905e-8, + 3.5761650960999997e-7, + 5.406555702509999e-8, + 1.91340425062e-8, + 4.05244277276e-8, + 1.67071698044e-8, + 2.64702379432e-7, + 4.54083719121e-8, + 1.15367276299e-8, + 7.01160189225e-8, + 2.12020626256e-7, + 7.55952714792e-8, + 3.35252445825e-8, + 6.410902643609999e-8, + 7.822972433139998e-8, + 3.00394443348e-8, + 1.85872035552e-7, + 3.21694096675e-8, + 1.9166603712099998e-8, + 1.4382528776500002e-7, + 2.30600946296e-7, + 1.1977210552999998e-7, + 3.21694096675e-8, + 3.1720115986e-7, + 5.00989110573e-12, + 2.14001834758e-9, + 3.57324647064e-7, + 9.836368168600001e-8, + 1.3317117896700002e-8, + 6.624100740240001e-8, + 3.0650079256e-8, + 3.23881793333e-8, + 0.0000010477687171799999, + 2.47766478953e-8, + 4.00638166198e-7, + 3.7385796368e-8, + 0.00000110210670495, + 5.16171069606e-9, + 5.5306060294599996e-8, + 7.43346458468e-8, + 2.98025726842e-8, + 4.50223643894e-8, + 2.6869636474599998e-11, + 2.23102995275e-7, + 6.624100740240001e-8, + 8.837339991869999e-8, + 1.0959679528299999e-7, + 7.70759415991e-8, + 9.19332979062e-8, + 5.72570744297e-9, + 5.67957997273e-12, + 7.200621520489999e-8, + 8.75570719476e-8, + 1.38879577383e-7, + 5.8323354775900006e-8, + 8.46519385822e-8, + 0.0000010404658225700002, + 2.7344550343299998e-8, + 1.1561451197599999e-7, + 3.37647982763e-7, + 1.03142857372e-7, + 3.0261981891400004e-8, + 1.0770523872e-7, + 5.56297659998e-8, + 4.45345220689e-7, + 5.190799176779999e-7, + 1.1878461076600001e-7, + 6.37944980645e-8, + 1.028044903e-7, + 2.35063847817e-8, + 3.35252445825e-8, + 1.75860650771e-7, + 5.95322200005e-8, + 2.3051930735100003e-7, + 1.01713704525e-7, + 6.36298925611e-8, + 8.32962182234e-9, + 1.73171410467e-7, + 5.92070463445e-8, + 1.35192178624e-7, + 1.80208181383e-7, + 2.32965100186e-7, + 5.558425986229999e-7, + 1.64668938007e-7, + 6.01836809013e-8, + 1.9915955477200002e-16, + 9.96792751761e-9, + 1.63404871286e-9, + 2.64702379432e-7, + 7.55162232084e-8, + 5.49833977189e-8, + 3.4953095347400004e-8, + 2.21025674493e-8, + 1.01029071417e-7, + 2.30733613826e-7, + 8.50266378712e-8, + 3.492997660290001e-8, + 1.72122175426e-7, + 6.06902637292e-8, + 2.0951701376400003e-8, + 5.13108366946e-7, + 2.80764979683e-7, + 7.49786710527e-7, + 1.28767098858e-7, + 0.00000130482668731, + 2.94524334014e-8, + 1.0383202068400001e-7, + 1.06529852732e-7, + 3.06223788373e-8, + 6.666061263539999e-8, + 2.77669768835e-7, + 1.9614212065399998e-7, + 7.57552863852e-9, + 1.3646260448700003e-8, + 1.55911616248e-8, + 4.2985875019e-8, + 5.35662859053e-7, + 1.31723026752e-7, + 2.8589493252999997e-8, + 6.15562220021e-7, + 2.48257838284e-8, + 5.54992004418e-8, + 1.59590984401e-7, + 1.05027747717e-7, + 4.16404749061e-15, + 3.21694096675e-8, + 1.55235536247e-8, + 7.22158660254e-8, + 7.3548078204e-11, + 5.12189467799e-8, + 5.78423562453e-7, + 7.34977455259e-8, + 8.428837152339999e-8, + 5.41683911418e-8, + 2.0892157394300002e-7, + 8.45875572871e-8, + 3.19669534548e-7, + 2.4721993929599997e-8, + 1.97866536768e-7, + 3.1078269037e-8, + 4.7958877370199995e-8, + 1.63190113114e-8, + 1.55306103512e-7, + 6.20692035531e-7, + 3.82587877803e-7, + 3.3292850458999995e-12, + 6.62976422611e-11, + 0.363112695543, + 1.2438406655e-7, + 1.57716890468e-7, + 8.270934005960001e-8, + 7.7356150975e-8, + 4.17240969082e-7, + 1.5340551258000003e-8, + 7.2558862077e-7, + 8.628154354439999e-8, + 0.00000130967390314, + 5.63969380635e-8 + ] + } + ], + "layout": { + "showlegend": false + } +} From 36cc37d11bd046c4e7d6bf20d8302f564a51d094 Mon Sep 17 00:00:00 2001 From: etienne Date: Tue, 22 May 2018 16:18:21 -0400 Subject: [PATCH 4/5] replace Scott's rule fallback with \propto (max - min) - to avoid "sharp" transitions from Silverman to Scott value - make custom bandwidth value use that same fallback when "too small" - rename "scott-rule" mock to "bandwidth-edge-cases" --- src/traces/violin/calc.js | 32 ++- .../baselines/violin_bandwidth-edge-cases.png | Bin 0 -> 21665 bytes test/image/baselines/violin_scott-rule.png | Bin 20338 -> 0 bytes ....json => violin_bandwidth-edge-cases.json} | 230 +++++++++++++++++- 4 files changed, 247 insertions(+), 15 deletions(-) create mode 100644 test/image/baselines/violin_bandwidth-edge-cases.png delete mode 100644 test/image/baselines/violin_scott-rule.png rename test/image/mocks/{violin_scott-rule.json => violin_bandwidth-edge-cases.json} (66%) diff --git a/src/traces/violin/calc.js b/src/traces/violin/calc.js index 5fd590f6195..eba21e821c8 100644 --- a/src/traces/violin/calc.js +++ b/src/traces/violin/calc.js @@ -71,7 +71,7 @@ module.exports = function calc(gd, trace) { return cd; }; -// Default to Silveman's rule of thumb, but if 'too small' use Scott's rule +// Default to Silveman's rule of thumb // - https://stats.stackexchange.com/a/6671 // - https://en.wikipedia.org/wiki/Kernel_density_estimation#A_rule-of-thumb_bandwidth_estimator // - https://github.com/statsmodels/statsmodels/blob/master/statsmodels/nonparametric/bandwidths.py @@ -80,21 +80,27 @@ function silvermanRule(len, ssd, iqr) { return 1.059 * a * Math.pow(len, -0.2); } -function scottRule(len, ssd) { - return ssd * Math.pow(len, -0.2); -} - function calcBandwidth(trace, cdi, vals) { - if(trace.bandwidth) return trace.bandwidth; - - var len = vals.length; - var ssd = Lib.stdev(vals, len - 1, cdi.mean); - var bw = silvermanRule(len, ssd, cdi.q3 - cdi.q1); + var bw; - if((cdi.max - cdi.min) / bw > 1e5) { - bw = scottRule(len, ssd); + if(trace.bandwidth) { + bw = trace.bandwidth; + } else { + var len = vals.length; + var ssd = Lib.stdev(vals, len - 1, cdi.mean); + bw = silvermanRule(len, ssd, cdi.q3 - cdi.q1); } - return bw; + + // Limit how small the bandwidth can be. + // + // Silverman's rule of thumb can be "very" small + // when IQR does a poor job at describing the spread + // of the distribution. + // We also want to limit custom bandwidths + // to not blow up kde computations. + return ((cdi.max - cdi.min) / bw) < 1e5 ? + bw : + (cdi.max - cdi.min) / 100; } function calcSpan(trace, cdi, valAxis, bandwidth) { diff --git a/test/image/baselines/violin_bandwidth-edge-cases.png b/test/image/baselines/violin_bandwidth-edge-cases.png new file mode 100644 index 0000000000000000000000000000000000000000..8bddcb7184e4b561c187bf731ced62341c5a8c66 GIT binary patch literal 21665 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 S;BV=X+`g%Oqfqr>$o~RJoeyXL diff --git a/test/image/mocks/violin_scott-rule.json b/test/image/mocks/violin_bandwidth-edge-cases.json similarity index 66% rename from test/image/mocks/violin_scott-rule.json rename to test/image/mocks/violin_bandwidth-edge-cases.json index a06692896d3..6d83421edbd 100644 --- a/test/image/mocks/violin_scott-rule.json +++ b/test/image/mocks/violin_bandwidth-edge-cases.json @@ -1,7 +1,7 @@ { "data": [ { - "name": "with scott rule bandwidth", + "name": "silverman value is too small", "type": "violin", "points": false, "y": [ @@ -227,7 +227,233 @@ }, { "bandwidth": 0.03364359551927969, - "name": "with custom bandwidth", + "name": "OK custom bandwidth", + "type": "violin", + "points": false, + "y": [ + 2.4403208885500003e-7, + 6.624100740240001e-8, + 8.164963286729999e-8, + 0.00000550607937631, + 3.02033017347e-8, + 3.7801716937800004e-7, + 5.56297659998e-8, + 5.406555702509999e-8, + 3.31213740697e-8, + 1.0835987313399999e-7, + 3.19669534548e-7, + 2.8017014902900004e-8, + 2.4514782933900002e-8, + 5.95554346643e-7, + 4.70654584492e-8, + 2.3361313822699997e-11, + 3.06469187871e-7, + 2.07771831308e-8, + 5.04663715295e-8, + 5.67592023418e-8, + 6.719484075659999e-8, + 2.3359219312100003e-9, + 7.32680903665e-8, + 1.56153538012e-7, + 5.92551838794e-8, + 6.48377885533e-8, + 6.5098659424e-8, + 1.92267340995e-7, + 6.27042106128e-10, + 3.79763712636e-8, + 5.79353363587e-8, + 2.01568499962e-7, + 4.5710354583899996e-8, + 8.68326386359e-8, + 2.00314121449e-7, + 4.16735959037e-11, + 1.05264632654e-7, + 1.3219377534799998e-8, + 1.1323983991099999e-7, + 7.9066491519e-9, + 3.29907596399e-7, + 3.58952178646e-7, + 3.06223788373e-8, + 1.34570962274e-7, + 1.95650463375e-7, + 8.88142553786e-8, + 6.33259714546e-7, + 7.89150230354e-8, + 3.44378121049e-8, + 3.56491902649e-8, + 7.17020398538e-8, + 0.00000117543109624, + 1.31723026752e-7, + 6.15562220021e-7, + 1.0411983170000001e-8, + 6.35306917979e-8, + 1.4244199622e-7, + 5.50507070561e-8, + 4.11937918362e-7, + 1.1436582759e-7, + 9.00381861905e-8, + 3.5761650960999997e-7, + 5.406555702509999e-8, + 1.91340425062e-8, + 4.05244277276e-8, + 1.67071698044e-8, + 2.64702379432e-7, + 4.54083719121e-8, + 1.15367276299e-8, + 7.01160189225e-8, + 2.12020626256e-7, + 7.55952714792e-8, + 3.35252445825e-8, + 6.410902643609999e-8, + 7.822972433139998e-8, + 3.00394443348e-8, + 1.85872035552e-7, + 3.21694096675e-8, + 1.9166603712099998e-8, + 1.4382528776500002e-7, + 2.30600946296e-7, + 1.1977210552999998e-7, + 3.21694096675e-8, + 3.1720115986e-7, + 5.00989110573e-12, + 2.14001834758e-9, + 3.57324647064e-7, + 9.836368168600001e-8, + 1.3317117896700002e-8, + 6.624100740240001e-8, + 3.0650079256e-8, + 3.23881793333e-8, + 0.0000010477687171799999, + 2.47766478953e-8, + 4.00638166198e-7, + 3.7385796368e-8, + 0.00000110210670495, + 5.16171069606e-9, + 5.5306060294599996e-8, + 7.43346458468e-8, + 2.98025726842e-8, + 4.50223643894e-8, + 2.6869636474599998e-11, + 2.23102995275e-7, + 6.624100740240001e-8, + 8.837339991869999e-8, + 1.0959679528299999e-7, + 7.70759415991e-8, + 9.19332979062e-8, + 5.72570744297e-9, + 5.67957997273e-12, + 7.200621520489999e-8, + 8.75570719476e-8, + 1.38879577383e-7, + 5.8323354775900006e-8, + 8.46519385822e-8, + 0.0000010404658225700002, + 2.7344550343299998e-8, + 1.1561451197599999e-7, + 3.37647982763e-7, + 1.03142857372e-7, + 3.0261981891400004e-8, + 1.0770523872e-7, + 5.56297659998e-8, + 4.45345220689e-7, + 5.190799176779999e-7, + 1.1878461076600001e-7, + 6.37944980645e-8, + 1.028044903e-7, + 2.35063847817e-8, + 3.35252445825e-8, + 1.75860650771e-7, + 5.95322200005e-8, + 2.3051930735100003e-7, + 1.01713704525e-7, + 6.36298925611e-8, + 8.32962182234e-9, + 1.73171410467e-7, + 5.92070463445e-8, + 1.35192178624e-7, + 1.80208181383e-7, + 2.32965100186e-7, + 5.558425986229999e-7, + 1.64668938007e-7, + 6.01836809013e-8, + 1.9915955477200002e-16, + 9.96792751761e-9, + 1.63404871286e-9, + 2.64702379432e-7, + 7.55162232084e-8, + 5.49833977189e-8, + 3.4953095347400004e-8, + 2.21025674493e-8, + 1.01029071417e-7, + 2.30733613826e-7, + 8.50266378712e-8, + 3.492997660290001e-8, + 1.72122175426e-7, + 6.06902637292e-8, + 2.0951701376400003e-8, + 5.13108366946e-7, + 2.80764979683e-7, + 7.49786710527e-7, + 1.28767098858e-7, + 0.00000130482668731, + 2.94524334014e-8, + 1.0383202068400001e-7, + 1.06529852732e-7, + 3.06223788373e-8, + 6.666061263539999e-8, + 2.77669768835e-7, + 1.9614212065399998e-7, + 7.57552863852e-9, + 1.3646260448700003e-8, + 1.55911616248e-8, + 4.2985875019e-8, + 5.35662859053e-7, + 1.31723026752e-7, + 2.8589493252999997e-8, + 6.15562220021e-7, + 2.48257838284e-8, + 5.54992004418e-8, + 1.59590984401e-7, + 1.05027747717e-7, + 4.16404749061e-15, + 3.21694096675e-8, + 1.55235536247e-8, + 7.22158660254e-8, + 7.3548078204e-11, + 5.12189467799e-8, + 5.78423562453e-7, + 7.34977455259e-8, + 8.428837152339999e-8, + 5.41683911418e-8, + 2.0892157394300002e-7, + 8.45875572871e-8, + 3.19669534548e-7, + 2.4721993929599997e-8, + 1.97866536768e-7, + 3.1078269037e-8, + 4.7958877370199995e-8, + 1.63190113114e-8, + 1.55306103512e-7, + 6.20692035531e-7, + 3.82587877803e-7, + 3.3292850458999995e-12, + 6.62976422611e-11, + 0.363112695543, + 1.2438406655e-7, + 1.57716890468e-7, + 8.270934005960001e-8, + 7.7356150975e-8, + 4.17240969082e-7, + 1.5340551258000003e-8, + 7.2558862077e-7, + 8.628154354439999e-8, + 0.00000130967390314, + 5.63969380635e-8 + ] + }, + { + "bandwidth": 1e-8, + "name": "custom bandwidth is too small", "type": "violin", "points": false, "y": [ From c55407079d9006f753156c4446b2bcd4104a1e9a Mon Sep 17 00:00:00 2001 From: etienne Date: Tue, 22 May 2018 16:43:35 -0400 Subject: [PATCH 5/5] fixup silverman valu fallback .. this time to "really" make the transition smooth --- src/traces/violin/calc.js | 24 +++++++++--------- .../baselines/violin_bandwidth-edge-cases.png | Bin 21665 -> 20971 bytes 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/traces/violin/calc.js b/src/traces/violin/calc.js index eba21e821c8..163f50a20ea 100644 --- a/src/traces/violin/calc.js +++ b/src/traces/violin/calc.js @@ -81,15 +81,7 @@ function silvermanRule(len, ssd, iqr) { } function calcBandwidth(trace, cdi, vals) { - var bw; - - if(trace.bandwidth) { - bw = trace.bandwidth; - } else { - var len = vals.length; - var ssd = Lib.stdev(vals, len - 1, cdi.mean); - bw = silvermanRule(len, ssd, cdi.q3 - cdi.q1); - } + var span = cdi.max - cdi.min; // Limit how small the bandwidth can be. // @@ -98,9 +90,17 @@ function calcBandwidth(trace, cdi, vals) { // of the distribution. // We also want to limit custom bandwidths // to not blow up kde computations. - return ((cdi.max - cdi.min) / bw) < 1e5 ? - bw : - (cdi.max - cdi.min) / 100; + + if(trace.bandwidth) { + return Math.max(trace.bandwidth, span / 1e4); + } else { + var len = vals.length; + var ssd = Lib.stdev(vals, len - 1, cdi.mean); + return Math.max( + silvermanRule(len, ssd, cdi.q3 - cdi.q1), + span / 100 + ); + } } function calcSpan(trace, cdi, valAxis, bandwidth) { diff --git a/test/image/baselines/violin_bandwidth-edge-cases.png b/test/image/baselines/violin_bandwidth-edge-cases.png index 8bddcb7184e4b561c187bf731ced62341c5a8c66..03b5a8b1f49f54cfe6164c6e62e74eb14cdadb0f 100644 GIT binary patch literal 20971 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 Lu6n@@%V+-sLRzI- literal 21665 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