diff --git a/draftlogs/5985_change.md b/draftlogs/5985_change.md new file mode 100644 index 00000000000..90f4977e620 --- /dev/null +++ b/draftlogs/5985_change.md @@ -0,0 +1 @@ +- Improve drawing the contour lines in non-linear space e.g. on log axes [[#5985](https://github.com/plotly/plotly.js/pull/5985)], with thanks to @andrew-matteson for the contribution! diff --git a/src/traces/contour/find_all_paths.js b/src/traces/contour/find_all_paths.js index 468c8407b63..dd7ba5e1efa 100644 --- a/src/traces/contour/find_all_paths.js +++ b/src/traces/contour/find_all_paths.js @@ -269,16 +269,25 @@ function getInterpPx(pi, loc, step) { var xa = pi.xaxis; var ya = pi.yaxis; + // Interpolate in linear space, then convert to pixel if(step[1]) { var dx = (pi.level - zxy) / (pi.z[locy][locx + 1] - zxy); + // Interpolate, but protect against NaN linear values for log axis (dx will equal 1 or 0) + var dxl = + (dx !== 1 ? (1 - dx) * xa.c2l(pi.x[locx]) : 0) + + (dx !== 0 ? dx * xa.c2l(pi.x[locx + 1]) : 0); - return [xa.c2p((1 - dx) * pi.x[locx] + dx * pi.x[locx + 1], true), + return [xa.c2p(xa.l2c(dxl), true), ya.c2p(pi.y[locy], true), locx + dx, locy]; } else { var dy = (pi.level - zxy) / (pi.z[locy + 1][locx] - zxy); + var dyl = + (dy !== 1 ? (1 - dy) * ya.c2l(pi.y[locy]) : 0) + + (dy !== 0 ? dy * ya.c2l(pi.y[locy + 1]) : 0); + return [xa.c2p(pi.x[locx], true), - ya.c2p((1 - dy) * pi.y[locy] + dy * pi.y[locy + 1], true), + ya.c2p(ya.l2c(dyl), true), locx, locy + dy]; } } diff --git a/test/image/baselines/contour_log.png b/test/image/baselines/contour_log.png index 8508a6bd7a5..6f3dea9aaa9 100644 Binary files a/test/image/baselines/contour_log.png and b/test/image/baselines/contour_log.png differ diff --git a/test/image/baselines/contour_nonlinear_interpolation.png b/test/image/baselines/contour_nonlinear_interpolation.png new file mode 100644 index 00000000000..482696505db Binary files /dev/null and b/test/image/baselines/contour_nonlinear_interpolation.png differ diff --git a/test/image/mocks/contour_nonlinear_interpolation.json b/test/image/mocks/contour_nonlinear_interpolation.json new file mode 100644 index 00000000000..16cc5204d12 --- /dev/null +++ b/test/image/mocks/contour_nonlinear_interpolation.json @@ -0,0 +1,72 @@ +{ + "data": [ + { + "x": [1,2,3,4,5], + "y": [1,2,3,4,5], + "z": [ + [0 , 3.1250, 12.5000, 28.1250, 50.0000], + [3.1250, 6.2500, 15.6250, 31.2500, 53.1250], + [12.5000, 15.6250, 25.0000, 40.6250, 62.5000], + [28.1250, 31.2500, 40.6250, 56.2500, 78.1250], + [50.0000, 53.1250, 62.5000, 78.1250, 100.0000] + ], + "contours": {"start": 10, "end": 90, "size": 10}, + "type": "contour" + }, + { + "x": [1,10,100,1000,10000], + "y": [1,2,3,4,5], + "z": [ + [0 , 3.1250, 12.5000, 28.1250, 50.0000], + [3.1250, 6.2500, 15.6250, 31.2500, 53.1250], + [12.5000, 15.6250, 25.0000, 40.6250, 62.5000], + [28.1250, 31.2500, 40.6250, 56.2500, 78.1250], + [50.0000, 53.1250, 62.5000, 78.1250, 100.0000] + ], + "contours": {"start": 10, "end": 90, "size": 10}, + "type": "contour", + "showscale": false, + "xaxis": "x2" + }, + { + "x": [1,2,3,4,5], + "y": [1,10,100,1000,10000], + "z": [ + [0 , 3.1250, 12.5000, 28.1250, 50.0000], + [3.1250, 6.2500, 15.6250, 31.2500, 53.1250], + [12.5000, 15.6250, 25.0000, 40.6250, 62.5000], + [28.1250, 31.2500, 40.6250, 56.2500, 78.1250], + [50.0000, 53.1250, 62.5000, 78.1250, 100.0000] + ], + "contours": {"start": 10, "end": 90, "size": 10}, + "type": "contour", + "showscale": false, + "yaxis": "y2" + }, + { + "x": [1,10,100,1000,10000], + "y": [1,10,100,1000,10000], + "z": [ + [0 , 3.1250, 12.5000, 28.1250, 50.0000], + [3.1250, 6.2500, 15.6250, 31.2500, 53.1250], + [12.5000, 15.6250, 25.0000, 40.6250, 62.5000], + [28.1250, 31.2500, 40.6250, 56.2500, 78.1250], + [50.0000, 53.1250, 62.5000, 78.1250, 100.0000] + ], + "contours": {"start": 10, "end": 90, "size": 10}, + "type": "contour", + "showscale": false, + "xaxis": "x2", + "yaxis": "y2" + } + ], + "layout": { + "xaxis": {"domain": [0, 0.45]}, + "xaxis2": {"domain": [0.55, 1], "type": "log"}, + "yaxis": {"domain": [0, 0.45]}, + "yaxis2": {"domain": [0.55, 1], "type": "log"}, + "margin": {"l": 50, "b": 50, "r": 110, "t": 10}, + "width": 500, + "height": 400 + } +}