Search code examples
layoutcolorsplotlyheatmapimshow

How to color a imshow chart based on a custom range


I'm working on a chart that works as a heatmap, but instead of a "traditional" color scale, I want to set a specific color to values between x and x+0.05;

The image below is a good visual example to illustrate what I want to do:

enter image description here

I have tried some approaches to do it but no one of them have worked.

Below is an MWE

import pandas as pd
import plotly.express as px

dict_vals = [
            {"user1": None, "user2": 0.906, "user3": 0.842},
            {"user1": 0.906, "user2": None, "user3": 0.527},
            {"user1": 0.842, "user2": 0.527, "user3": None},
        ]

matrix_df=pd.DataFrame.from_dict(dict_vals)
fig = px.imshow(
    matrix_df,
    x=matrix_df.columns,
    y=matrix_df.columns,
    zmin=0.75,
    zmax=0.95,
    text_auto=True,
    aspect="auto"
)
colors = [
    "rgb(214, 11, 67)",
    "rgb(255, 107, 0)",
    "rgb(255, 201, 77)",
    "rgb(168, 227, 0)",
    "rgb(65, 175, 26)",
    ]

fig.update_coloraxes(
    showscale=False,
    colorscale=[
        (0.0, colors[0]),
        (0.8, colors[1]),
        (0.85, colors[2]),
        (0.9, colors[3]),
        (0.95, colors[4]),
        (1, colors[4]),
    ],
)

If you have any reference about how to solve this, I will be very grateful


Solution

  • I found a way to do what I was looking for

    import pandas as pd
    import plotly.express as px
    import numpy as np
    
    dict_vals = [
                {"user1": None, "user2": 0.906, "user3": 0.842},
                {"user1": 0.906, "user2": None, "user3": 0.527},
                {"user1": 0.842, "user2": 0.527, "user3": None},
            ]
    
    matrix_df=pd.DataFrame.from_dict(dict_vals)
    
    color_list=[[0, colors[0]],
        [0.80, colors[0]], 
        [0.80, colors[1]],  
        [0.85, colors[1]],
        [0.85, colors[2]], 
        [0.90, colors[2]],
        [0.90, colors[3]], 
        [0.95, colors[3]],  
        [0.95, colors[4]],
        [1.00, colors[4]]]
    
    fig = px.imshow(
        matrix_df.values,
        x=matrix_df.columns,
        y=matrix_df.columns,
        zmin=0,
        zmax=1,
        text_auto=True,
        aspect="auto",
        color_continuous_scale=color_list
    )
    fig.update_coloraxes(showscale=True)
    

    The result will be: enter image description here

    I hope it can help someone in the future.

    Regards, Leonardo