1

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).

Basj
  • 41,386
  • 99
  • 383
  • 673

2 Answers2

1

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>
K Scandrett
  • 16,390
  • 4
  • 40
  • 65
  • Thanks! Since you're using `zValues[0]`, the length of `x` will be the length of only one row of `z`. Does Plotly understand if `z` is of shape 100x100 and `x` of shape only 100? – Basj Jan 11 '23 at 07:59
  • 1
    Should do. I'm using the count of the items in the first inner array for that reason (`[1, 2, 3, 4]`). In your case with a 100 by 100 matrix that should be a count of 100. Your example is a 4 x 2 and my code spreads the 4 X-values. – K Scandrett Jan 11 '23 at 08:33
-1

You can use the range property of the xaxis object. This property takes an array of two values, representing the minimum and maximum values for the x-axis.

var data = [{z: [[1, 2, 3, 4], [5, 6, 7, 8]], type: 'heatmap'}];

var layout = {
  xaxis: {
    range: [0, 321],
    ticksuffix: " mm"
  }
};

Plotly.newPlot('myDiv', data, layout);
<script src="https://cdn.plot.ly/plotly-2.16.2.min.js"></script>
<div id="myDiv"></div>
Basj
  • 41,386
  • 99
  • 383
  • 673
  • I converted your answer into runnable snippet. Unfortunately, `range` doesn't work, see example: the plot doesn't use full width from left to right. – Basj Jan 03 '23 at 09:32
  • @Basj Given the data is clustered at one end, why would the plot cover the full width when displaying a range from 0 to 321? – K Scandrett Jan 10 '23 at 11:50
  • @KScandrett The range `[0, 3]` should be rescaled to `[0, 321]`. – Basj Jan 10 '23 at 13:04