Search code examples
pythonplotlyplotly-dashheatmapwaffle-chart

Legend label Heatmap Plotly


I am trying to build a waffle chart out of a heatmap in Plotly. Code is working well, but now instead of having a legend based on the numerical data, I want to show the text ( i.e Moderate distance to target" instead of 2). Any idea how to move forward? Thanks!

m= 10
n= 10
z = np.ones((m, n))
z[2:, 6] = 2
z[:4, 7] = 2
z[4:, 7] = 3
z[:4, 8] = 3
z[4:, 8] = 4
z[:5, 9] = 5
z[5:, 9] = 6

#dictionary that maps the heatmap z-values to strings
d = {1: "Insufficient data",
    2: "Moderate distance to target",
    3: "Close to target",
    4: "Far from target",
    5: "Very far from target",
    6: "Target met or almost met",
    }

M = max([len(s) for s in d.values()])
customdata= np.empty((m,n), dtype=f'<U{M}')  #supplementary information on each waffle cell

colorscale = [[0, "#adb5bd"],
              [0.16, "#adb5bd"],
              [0.16, "#ffc107"],
              [0.33,  "#ffc107"],
              [0.33,  "#28a745"],
              [0.5,  "#28a745"],
              [0.5,  "#d76406"],
              [0.66,  "#d76406"],
              [0.66,  "#dc3545"],
              [0.83, "#dc3545" ],
              [0.83, "#007bff" ],
              [1, "#007bff"]]

ticktext = ["Insufficient data", "Moderate distance to target", "Close to target", "Far from target", "Very far from target","Target met or almost met"]
xlabels = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J']
ylabels = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J']

fig = go.Figure(go.Heatmap(x=xlabels, y = ylabels, z=z,
                           customdata=customdata, xgap=3, ygap=3,
                           colorscale=colorscale, showscale=True,
                           hovertemplate="(%{y}, %{x}): %{customdata})<extra></extra>"))
fig.update_layout(margin=dict(l=40, r=20, t=20, b=40),yaxis_autorange='reversed')
fig.update_yaxes(showticklabels=False)
fig.update_xaxes(showticklabels=False)
[enter image description here][1]fig.update_traces(colorbar_orientation='h', selector=dict(type='heatmap'))

Solution

  • This is accomplished by setting the string you wish to set and the value of the color bar (the position you wish to display). Just understand that the scale values you set here are for your graph and string length, so you will need to manually modify them if you change the graph size or string.

    fig = go.Figure(go.Heatmap(x=xlabels, 
                               y=ylabels,
                               z=z,
                               customdata=customdata,
                               xgap=2,
                               ygap=2,
                               colorscale=colorscale,
                               showscale=True,
                               hovertemplate="(%{y}, %{x}): %{customdata})<extra></extra>",
                              )
                   )
    fig.update_traces(colorbar_orientation='h',
                      colorbar_tickmode='array',
                      colorbar_ticktext=ticktext,
                      colorbar_tickvals=[1.30, 2.25, 3.0, 3.8, 4.75, 5.65],
                      colorbar_tickangle=0,
                      selector=dict(type='heatmap')
                     )
    fig.update_yaxes(showticklabels=False)
    fig.update_xaxes(showticklabels=False)
    
    fig.show()
    

    enter image description here