diff --git a/draftlogs/6891_change.md b/draftlogs/6891_change.md new file mode 100644 index 00000000000..5490bfd4ec1 --- /dev/null +++ b/draftlogs/6891_change.md @@ -0,0 +1 @@ +- Improve rendering of heatmap bricks for log-scale axes [[#5991](https://github.com/plotly/plotly.js/issues/5991)], with thanks to @andrew-matteson for the contribution! diff --git a/src/traces/heatmap/make_bound_array.js b/src/traces/heatmap/make_bound_array.js index d6b30629cdb..e2deffe4ddb 100644 --- a/src/traces/heatmap/make_bound_array.js +++ b/src/traces/heatmap/make_bound_array.js @@ -24,11 +24,25 @@ module.exports = function makeBoundArray(trace, arrayIn, v0In, dvIn, numbricks, // contour plots only want the centers if(isContour || isGL2D) arrayOut = Array.from(arrayIn).slice(0, numbricks); else if(numbricks === 1) { - arrayOut = [arrayIn[0] - 0.5, arrayIn[0] + 0.5]; + if(ax.type === 'log') { + arrayOut = [0.5 * arrayIn[0], 2 * arrayIn[0]]; + } else { + arrayOut = [arrayIn[0] - 0.5, arrayIn[0] + 0.5]; + } + } else if(ax.type === 'log') { + arrayOut = [Math.pow(arrayIn[0], 1.5) / Math.pow(arrayIn[1], 0.5)]; + + for(i = 1; i < len; i++) { + // Geomean + arrayOut.push(Math.sqrt(arrayIn[i - 1] * arrayIn[i])); + } + + arrayOut.push(Math.pow(arrayIn[len - 1], 1.5) / Math.pow(arrayIn[len - 2], 0.5)); } else { arrayOut = [1.5 * arrayIn[0] - 0.5 * arrayIn[1]]; for(i = 1; i < len; i++) { + // Arithmetic mean arrayOut.push((arrayIn[i - 1] + arrayIn[i]) * 0.5); } @@ -37,11 +51,21 @@ module.exports = function makeBoundArray(trace, arrayIn, v0In, dvIn, numbricks, if(len < numbricks) { var lastPt = arrayOut[arrayOut.length - 1]; - var delta = lastPt - arrayOut[arrayOut.length - 2]; + var delta; // either multiplicative delta (log axis type) or arithmetic delta (all other axis types) + if(ax.type === 'log') { + delta = lastPt / arrayOut[arrayOut.length - 2]; + + for(i = len; i < numbricks; i++) { + lastPt *= delta; + arrayOut.push(lastPt); + } + } else { + delta = lastPt - arrayOut[arrayOut.length - 2]; - for(i = len; i < numbricks; i++) { - lastPt += delta; - arrayOut.push(lastPt); + for(i = len; i < numbricks; i++) { + lastPt += delta; + arrayOut.push(lastPt); + } } } } else { diff --git a/test/image/baselines/zz-heatmap-log-scale.png b/test/image/baselines/zz-heatmap-log-scale.png new file mode 100644 index 00000000000..cfebfb6a999 Binary files /dev/null and b/test/image/baselines/zz-heatmap-log-scale.png differ diff --git a/test/image/mocks/zz-heatmap-log-scale.json b/test/image/mocks/zz-heatmap-log-scale.json new file mode 100644 index 00000000000..71fafa3cd9f --- /dev/null +++ b/test/image/mocks/zz-heatmap-log-scale.json @@ -0,0 +1,47 @@ +{ + "data": [ + { + "type": "heatmap", + "x": [ + 0.0001, + 0.001, + 0.01 + ], + "y": [ + 0.0001, + 0.001, + 0.01 + ], + "z": [ + [ + 1, + 2, + 3 + ], + [ + 3, + 2, + 1 + ], + [ + 7, + 2, + 7 + ] + ] + } + ], + "layout": { + "title": {"text": "log scale heatmap"}, + "xaxis": { + "type": "log" + }, + "yaxis": { + "type": "log" + }, + "height": 598, + "width": 1080, + "autosize": true, + "showlegend": false + } +}