Search code examples
javascriptplotlyplotly.js

Custom x-axis and y-axis range with Plotly heatmap


Let's say we have a 2x4 matrix displayed into a Plotly.js heatmap (in reality it can be 500x1000):

var data = [{z: [[1, 2, 3, 4], [5, 6, 7, 8]], type: 'heatmap'}];
Plotly.newPlot('myDiv', data, {xaxis: { ticksuffix: " mm" }}, {});
<script src="https://cdn.plot.ly/plotly-2.16.2.min.js"></script>
<div id="myDiv"></div>

How to change the x-axis to a custom range, and keep the plot full width?

For example 0 mm to 321 mm (unit is millimiter), instead of -0.5mm to 3.5mm ?

PS: since the data can be big (500x1000 pixels), I'd like to avoid to have to insert x, y values in data itself, because it would make this object 3 times bigger (and the rendering is slow enough).


Solution

  • You can scale the x axis labels with a function.

    Uncomment the console.log() statement if you want to see what values it's calculating.

    var zValues = [[1, 2, 3, 4], [5, 6, 7, 8]];
    
    var max = 321;
    var multiplier = max / (zValues[0].length - 1);
    
    var data = [{
      z: zValues
      , type: 'heatmap'
      , x: zValues[0].map(function(el, idx) { /* console.log(idx, idx * multiplier); */ return idx * multiplier; }),
    }];
    
    
    Plotly.newPlot('myDiv', data, {xaxis: { ticksuffix: " mm" }}, {});
    <script src="https://cdn.plot.ly/plotly-2.16.2.min.js"></script>
    <div id="myDiv"></div>

    If you don't want the first point at 0 (sending the first x axis mark negative) then you can change the formula to

    var zValues = [[1, 2, 3, 4], [5, 6, 7, 8]];
    
    var max = 321;
    var multiplier = max / (zValues[0].length);
    
    var data = [{
      z: zValues
      , type: 'heatmap'
      , x: zValues[0].map(function(el, idx) { /* console.log(idx, idx * multiplier + multiplier); */ return idx * multiplier + multiplier; }),
    }];
    
    
    Plotly.newPlot('myDiv', data, {xaxis: { ticksuffix: " mm" }}, {});
    <script src="https://cdn.plot.ly/plotly-2.16.2.min.js"></script>
    <div id="myDiv"></div>