I'm working on code that produces a plotly heatmap in JavaScript. The problem I am facing is that for data with log2FoldChange values between the range of -0.1, 0.1, the color being displayed is a shade of gray, instead of the white that I am defining with #FFFFFF. Below is my code:
// Create heatmap data
let heatmap_data = [{
z: total_L2FC,
x: indiv_name_list,
y: gene_list,
type: 'heatmap',
hovertemplate: 'Gene: %{y}<br>Individual: %{x}<br>log2FoldChange: %{z}<br>p-adj: %{customdata}<extra></extra>',
customdata: total_padj,
zmin: -4,
zmax: 4,
colorscale: [
[-4, '#000A63'],
[-3, '#000A63'],
[-3, '#000D84'],
[-2.67, '#000D84'],
[-2.67, '#1C2892'],
[-2.33, '#1C2892'],
[-2.33, '#39439F'],
[-2, '#39439F'],
[-2, '#555EAD'],
[-1.67, '#555EAD'],
[-1.67, '#7179BB'],
[-1.33, '#7179BB'],
[-1.33, '#8E93C8'],
[-1, '#8E93C8'],
[-1, '#AAAED6'],
[-0.67, '#AAAED6'],
[-0.67, '#C6C9E4'],
[-0.33, '#C6C9E4'],
[-0.33, '#E3E4F1'],
[-0.10, '#E3E4F1'],
[-0.10, '#FFFFFF'],
[0.10, '#FFFFFF'],
[0.10, '#F6E3E3'],
[0.33, '#F6E3E3'],
[0.33, '#EDC7C6'],
[0.67, '#EDC7C6'],
[0.67, '#E4ABAA'],
[1, '#E4ABAA'],
[1, '#DB8F8E'],
[1.33, '#DB8F8E'],
[1.33, '#D37371'],
[1.67, '#D37371'],
[1.67, '#CA5755'],
[2, '#CA5755'],
[2, '#C13B39'],
[2.33, '#C13B39'],
[2.33, '#B81F1C'],
[2.67, '#B81F1C'],
[2.67, '#AF0300'],
[3, '#AF0300'],
[4, '#970300'],
],
autocolorscale: false,
hoverongaps: false,
xaxis: {
tickangle: 45
},
yaxis: {
autorange: true
},
colorbar: {
title: {
text: 'log<sub>2</sub>FC',
font: {
size: 14
}
}
},
showscale: true,
}];
let layout = {
height: fig1_height,
width: fig1_width,
xaxis: {
title: {
text: 'Individual',
font: {
size: 14
}
}
},
yaxis: {
title: {
text: 'Gene',
font: {
size: 14
}
}
}
};
console.log('fig1_width:', fig1_width);
// Resolve the Promise with the generated heatmap data and layout
resolve({ heatmap_data, layout, fig1_title });
I have tried adjusting what seems like all of the settings I could from the plotly documentation on Heatmap Discretized Colorscales as well as the general Heatmap page.
I have also tried reversing the order of defining the colorscale, changing them to rgb instead of hexscale, and changing the zmin-zmax to be within the colorscale range and outside of it.
Please help. I have been working through this issue for almost a week and can't for the life of me figure out what is wrong.
You need to normalize the values for the colorscale so that they fit the scale [0, 1]
. Also, one value is missing at the end :
...
[2.67, '#AF0300'],
[3, '#AF0300'],
[3, '#AF0300'], // <- missing
[4, '#970300'],
To normalize the values, you can do something like :
const normalize = v => (v - zmin) / (zmax - zmin);
colorscale.map(([v, color]) => [normalize(v), color])