Search code examples
javascriptplotlyheatmapplotly.js

Select or highlight points on a Plotly heatmap


Let's say we have a heatmap:

const z = Array.from({length: 250}, () => Array.from({length: 500}, () => Math.floor(Math.random() * 10)));
Plotly.newPlot('plot',  [{z: z, type: 'heatmap'}]);
document.getElementById("go").onclick = () => { alert(); }
<script src="https://cdn.plot.ly/plotly-2.26.0.min.js"></script>
<button id="go">Click to focus the pixels > 5</button>
<div id="plot"></div>

Let's say we have a threshold = 5.

How to empahsize/highlight pixels that are above the threshold? Or maybe it's easier to make transparent or grey the pixels which are below the threshold.

The goal is to visually put the focus on the pixels above the threshold.

How to do this with Plotly.js?


Solution

  • If you can define a discrete value range for pixels (ex. min 0 and max 10), then you can define your threshold as a percentage value and use it to define a custom colorscale.

    const min = 0;
    const max = 10;
    
    const z = Array.from({length: 100}, () => Array.from({length: 100}, () => Math.floor(Math.random() * max)));
    
    const threshold = 5; // value included in the highlighted range
    const breakpoint = threshold / max; // (percentage from 0.0 to 1.0)
    
    const colorscaleValue = [
      [0.0, 'white'],
      [breakpoint, 'white'],
      [breakpoint, 'red'],
      [1, 'red']
    ];
    
    
    Plotly.newPlot('plot',  [{z: z, type: 'heatmap', colorscale: colorscaleValue}]);
    <script src="https://cdn.plot.ly/plotly-2.26.0.min.js"></script>
    <div id="plot"></div>

    As you can see, all values in the first half of the range (50%, 0 to 5 pixels excluded) will be shown in white while values above the 50% (5 to 10, 5 included) will be shown in red. In my example i'm using just two colors to define values above and below your threshold. If you want to use a different colorscale, you can try this:

    const min = 0;
    const max = 10;
    
    const z = Array.from({length: 250}, () => Array.from({length: 500}, () => Math.floor(Math.random() * 10)));
    
    
    const threshold = 5; // value included in the highlighted range
    const breakpoint = threshold / max; // (percentage from 0.0 to 1.0)
    
    const colorscaleValue = [
      [0.0, 'rgba(169,169,169,0.5)'],
      [breakpoint, 'rgba(169,169,169,0.5)'],
      [breakpoint, 'rgb(220,170,132)'],
      [1, 'rgb(178,10,28)'],
    ];
    
    
    Plotly.newPlot('plot',  [{z: z, type: 'heatmap', colorscale: colorscaleValue}]);
    <script src="https://cdn.plot.ly/plotly-2.26.0.min.js"></script>
    <div id="plot"></div>

    You can of course set as many "breakpoints" as you wish in your colorscale, remember only that values goes from 0.0 to 1.0 and they represent the value range in percentage.