Search code examples
javascriptplotlyvisualizationplotly.js

Plotly.js Heatmap Coloring Issue: Getting Grays instead of Whites


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.


Solution

  • 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])