From 2f9fa3b1a7fe4bebce8ce8726bcc39f5bf4f1261 Mon Sep 17 00:00:00 2001 From: Shumpei Shiina Date: Tue, 15 Oct 2019 23:14:02 -0500 Subject: [PATCH 1/2] Fix width of box plots with log-scale axis --- src/plots/cartesian/autorange.js | 29 +++++--- src/traces/box/cross_trace_calc.js | 4 +- src/traces/box/hover.js | 2 +- src/traces/box/plot.js | 27 +++---- test/image/baselines/box_log_scale.png | Bin 0 -> 16324 bytes test/image/mocks/box_log_scale.json | 94 +++++++++++++++++++++++++ 6 files changed, 130 insertions(+), 26 deletions(-) create mode 100644 test/image/baselines/box_log_scale.png create mode 100644 test/image/mocks/box_log_scale.json diff --git a/src/plots/cartesian/autorange.js b/src/plots/cartesian/autorange.js index 2b8a176d747..ca3b16805cb 100644 --- a/src/plots/cartesian/autorange.js +++ b/src/plots/cartesian/autorange.js @@ -298,6 +298,8 @@ function doAutoRange(gd, ax) { * (unless one end is overridden by tozero) * tozero: (boolean) make sure to include zero if axis is linear, * and make it a tight bound if possible + * vpadLinearized: (boolean) whether or not vpad (or vpadplus/vpadminus) + * is linearized (for log scale axes) * * @return {object} * - min {array of objects} @@ -320,6 +322,7 @@ function findExtremes(ax, data, opts) { var tozero = opts.tozero && (ax.type === 'linear' || ax.type === '-'); var isLog = ax.type === 'log'; var hasArrayOption = false; + var vpadLinearized = opts.vpadLinearized || false; var i, v, di, dmin, dmax, ppadiplus, ppadiminus, vmin, vmax; function makePadAccessor(item) { @@ -371,16 +374,22 @@ function findExtremes(ax, data, opts) { if(!isNumeric(di)) return; ppadiplus = ppadplus(i); ppadiminus = ppadminus(i); - vmin = di - vpadminus(i); - vmax = di + vpadplus(i); - // special case for log axes: if vpad makes this object span - // more than an order of mag, clip it to one order. This is so - // we don't have non-positive errors or absurdly large lower - // range due to rounding errors - if(isLog && vmin < vmax / 10) vmin = vmax / 10; - - dmin = ax.c2l(vmin); - dmax = ax.c2l(vmax); + + if(vpadLinearized) { + dmin = ax.c2l(di) - vpadminus(i); + dmax = ax.c2l(di) + vpadplus(i); + } else { + vmin = di - vpadminus(i); + vmax = di + vpadplus(i); + // special case for log axes: if vpad makes this object span + // more than an order of mag, clip it to one order. This is so + // we don't have non-positive errors or absurdly large lower + // range due to rounding errors + // if(isLog && vmin < vmax / 10) vmin = vmax / 10; + + dmin = ax.c2l(vmin); + dmax = ax.c2l(vmax); + } if(tozero) { dmin = Math.min(0, dmin); diff --git a/src/traces/box/cross_trace_calc.js b/src/traces/box/cross_trace_calc.js index a13f701c47b..b1792cb9794 100644 --- a/src/traces/box/cross_trace_calc.js +++ b/src/traces/box/cross_trace_calc.js @@ -60,7 +60,7 @@ function setPositionOffset(traceType, gd, boxList, posAxis) { for(i = 0; i < boxList.length; i++) { calcTrace = calcdata[boxList[i]]; for(j = 0; j < calcTrace.length; j++) { - pointList.push(calcTrace[j].pos); + pointList.push(posAxis.c2l(calcTrace[j].pos, true)); shownPts += (calcTrace[j].pts2 || []).length; } } @@ -125,7 +125,6 @@ function setPositionOffset(traceType, gd, boxList, posAxis) { t.bPos = bPos; t.bdPos = bdPos; t.wHover = wHover; - // box/violin-only value-space push value var pushplus; var pushminus; @@ -213,6 +212,7 @@ function setPositionOffset(traceType, gd, boxList, posAxis) { padded: padded, vpadminus: vpadminus, vpadplus: vpadplus, + vpadLinearized: true, // N.B. SVG px-space positive/negative ppadminus: {x: ppadminus, y: ppadplus}[axLetter], ppadplus: {x: ppadplus, y: ppadminus}[axLetter], diff --git a/src/traces/box/hover.js b/src/traces/box/hover.js index 0eac65f7669..8e40188841b 100644 --- a/src/traces/box/hover.js +++ b/src/traces/box/hover.js @@ -60,7 +60,7 @@ function hoverOnBoxes(pointData, xval, yval, hovermode) { var boxDelta = t.bdPos; var boxDeltaPos, boxDeltaNeg; var posAcceptance = t.wHover; - var shiftPos = function(di) { return di.pos + t.bPos - pVal; }; + var shiftPos = function(di) { return pAxis.c2l(di.pos) + t.bPos - pAxis.c2l(pVal); }; if(isViolin && trace.side !== 'both') { if(trace.side === 'positive') { diff --git a/src/traces/box/plot.js b/src/traces/box/plot.js index 3a1eefdfa85..1f6d3432c66 100644 --- a/src/traces/box/plot.js +++ b/src/traces/box/plot.js @@ -86,16 +86,16 @@ function plotBoxAndWhiskers(sel, axes, trace, t) { paths.each(function(d) { if(d.empty) return 'M0,0Z'; - var pos = d.pos; - var posc = posAxis.c2p(pos + bPos, true) + bPosPxOffset; - var pos0 = posAxis.c2p(pos + bPos - bdPos0, true) + bPosPxOffset; - var pos1 = posAxis.c2p(pos + bPos + bdPos1, true) + bPosPxOffset; - var posw0 = posAxis.c2p(pos + bPos - wdPos, true) + bPosPxOffset; - var posw1 = posAxis.c2p(pos + bPos + wdPos, true) + bPosPxOffset; - var posm0 = posAxis.c2p(pos + bPos - bdPos0 * nw, true) + bPosPxOffset; - var posm1 = posAxis.c2p(pos + bPos + bdPos1 * nw, true) + bPosPxOffset; - var q1 = valAxis.c2p(d.q1, true); - var q3 = valAxis.c2p(d.q3, true); + var lcenter = posAxis.c2l(d.pos + bPos, true); + var posc = posAxis.l2p(lcenter) + bPosPxOffset; + var pos0 = posAxis.l2p(lcenter - bdPos0) + bPosPxOffset; + var pos1 = posAxis.l2p(lcenter + bdPos1) + bPosPxOffset; + var posw0 = posAxis.l2p(lcenter - wdPos) + bPosPxOffset; + var posw1 = posAxis.l2p(lcenter + wdPos) + bPosPxOffset; + var posm0 = posAxis.l2p(lcenter - bdPos0 * nw) + bPosPxOffset; + var posm1 = posAxis.l2p(lcenter + bdPos1 * nw) + bPosPxOffset; + var q1 = valAxis.l2p(d.q1, true); + var q3 = valAxis.l2p(d.q3, true); // make sure median isn't identical to either of the // quartiles, so we can see it var m = Lib.constrain( @@ -288,9 +288,10 @@ function plotBoxMean(sel, axes, trace, t) { paths.exit().remove(); paths.each(function(d) { - var posc = posAxis.c2p(d.pos + bPos, true) + bPosPxOffset; - var pos0 = posAxis.c2p(d.pos + bPos - bdPos0, true) + bPosPxOffset; - var pos1 = posAxis.c2p(d.pos + bPos + bdPos1, true) + bPosPxOffset; + var lcenter = posAxis.c2l(d.pos + bPos, true); + var posc = posAxis.l2p(lcenter) + bPosPxOffset; + var pos0 = posAxis.l2p(lcenter - bdPos0) + bPosPxOffset; + var pos1 = posAxis.l2p(lcenter + bdPos1) + bPosPxOffset; var m = valAxis.c2p(d.mean, true); var sl = valAxis.c2p(d.mean - d.sd, true); var sh = valAxis.c2p(d.mean + d.sd, true); diff --git a/test/image/baselines/box_log_scale.png b/test/image/baselines/box_log_scale.png new file mode 100644 index 0000000000000000000000000000000000000000..c6f6995db35d70623f90ff806ba3010c1a2c9d3c GIT binary patch literal 16324 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 UDEY1M>wLCTx`sL#zg@ijUo>CdK>z>% literal 0 HcmV?d00001 diff --git a/test/image/mocks/box_log_scale.json b/test/image/mocks/box_log_scale.json new file mode 100644 index 00000000000..e9160f2e346 --- /dev/null +++ b/test/image/mocks/box_log_scale.json @@ -0,0 +1,94 @@ +{ + "data": [ + { + "y": [ + 1.0, + 1.1, + 1.0, + 0.9, + 1.2, + 2.0, + 1.5, + 2.3, + 1.7, + 2.2, + 1.0, + 1.1, + 1.2, + 0.9, + 1.1 + ], + "x": [ + 1, + 1, + 1, + 1, + 1, + 10, + 10, + 10, + 10, + 10, + 100, + 100, + 100, + 100, + 100 + ], + "type": "box" + }, + { + "y": [ + 2.2, + 2.3, + 2.0, + 2.5, + 2.1, + 0.1, + 0.5, + 0.8, + 0.3, + 0.3, + 1.1, + 1.2, + 0.9, + 1.0, + 1.0, + 2.4, + 2.0, + 1.5, + 1.6, + 1.9 + ], + "x": [ + 1, + 1, + 1, + 1, + 1, + 10, + 10, + 10, + 10, + 10, + 50, + 50, + 50, + 50, + 50, + 100, + 100, + 100, + 100, + 100 + ], + "type": "box", + "boxmean": true + } + ], + "layout": { + "xaxis": { + "type": "log" + } + } +} From 370e61a25005978d70f716ee38d391dbfa66e21a Mon Sep 17 00:00:00 2001 From: Shumpei Shiina Date: Wed, 16 Oct 2019 19:54:30 -0500 Subject: [PATCH 2/2] Don't use linearized values on value axes in box plots --- src/traces/box/plot.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/traces/box/plot.js b/src/traces/box/plot.js index 1f6d3432c66..e6e6bec935e 100644 --- a/src/traces/box/plot.js +++ b/src/traces/box/plot.js @@ -94,8 +94,8 @@ function plotBoxAndWhiskers(sel, axes, trace, t) { var posw1 = posAxis.l2p(lcenter + wdPos) + bPosPxOffset; var posm0 = posAxis.l2p(lcenter - bdPos0 * nw) + bPosPxOffset; var posm1 = posAxis.l2p(lcenter + bdPos1 * nw) + bPosPxOffset; - var q1 = valAxis.l2p(d.q1, true); - var q3 = valAxis.l2p(d.q3, true); + var q1 = valAxis.c2p(d.q1, true); + var q3 = valAxis.c2p(d.q3, true); // make sure median isn't identical to either of the // quartiles, so we can see it var m = Lib.constrain(