✊🏿 Black Lives Matter. Please consider donating to Black Girls Code today.
🐇 Announcing Dash VTK for 3d simulation graphics. Check out the March webinar.

How to define the Z argument for the create_annotated_heatmap() function?

Hi All,

I’m brand new to Plotly and Dash. I’m trying to create a heat map.

The docs at https://plotly.com/python/heatmaps/ say that it’s possible to use the ff.create_annotated_heatmap() function, as follows:

import plotly.figure_factory as ff

z = [[.1, .3, .5],
     [1.0, .8, .6],
     [.6, .4, .2]]

x = ['Team A', 'Team B', 'Team C']
y = ['Game Three', 'Game Two', 'Game One']

z_text = [['Win', 'Lose', 'Win'],
          ['Lose', 'Lose', 'Win'],
          ['Win', 'Win', 'Lose']]

fig = ff.create_annotated_heatmap(z, x=x, y=y, annotation_text=z_text, colorscale='Viridis')
fig.show()

The first argument, data, seems to be a list of lists.

My data looks as follows:

df = pd.DataFrame({'Make':['Ford', 'Ford', 'Ford', 'Buick', 'Buick', 'Buick', 'Mercedes', 'Mercedes', 'Mercedes'],
                          'Score':['88.6', '76.6', '86.2', '79.1', '86.8', '96.4', '97.3', '98.7', '98.5'],
                          'Dimension':['Speed', 'MPG', 'Styling', 'Speed', 'MPG', 'Styling', 'Speed', 'MPG', 'Styling'],
                          'Month':['Apr-19', 'Apr-19', 'Apr-19', 'Apr-19', 'Apr-19', 'Apr-19', 'Apr-19', 'Apr-19', 'Apr-19']})

And, my code is as follows:

ford_scores = df[(df['Make'].isin(['Ford']))]['Score'].astype(float).tolist()
buick_scores = df[(df['Make'].isin(['Buick']))]['Score'].astype(float).tolist()
mercedes_scores = df[(df['Make'].isin(['Mercedes']))]['Score'].astype(float).tolist()

import plotly.figure_factory as ff
fig = ff.create_annotated_heatmap(
            z=[ford_scores, buick_scores, mercedes_scores],
            x=df['Dimension'].unique().tolist(),
            y=df['Make'].unique().tolist(),
            colorscale=['red', 'orange', 'yellow', 'green'],
            hoverongaps=False
            )

fig.show()

This code works, but it breaks down spectacularly when the values in the Make column are something other than “Ford”, “Buick” or “Mercedes” (or if the number of elements increases or decreases).

As you can see, I’m manually defining the ford_scores, buick_scores and mercedes_scores before passing them to the Z argument.

Is there a way to pass in the ‘df’ data frame to the Z argument such that the function “understands” that the Z argument consists of the values in the ‘Score’ column? If not, is there another way to pass in the Z argument such that doing so doesn’t require advance knowledge of the data and pre-processing the lists? (i.e. so that it’s flexible)

Thanks!

Try this:

df['Score'] = pd.to_numeric(df['Score'])
df = pd.pivot_table(df, values='Score', index='Make', columns=['Dimension'])

import plotly.figure_factory as ff
fig = ff.create_annotated_heatmap(
            z=df.to_numpy(),
            x=df.columns.tolist(),
            y=df.index.tolist(),
            colorscale=['red', 'orange', 'yellow', 'green'],
            hoverongaps=False
            )

fig.show()

@AnnMarieW – this works beautifully, thank you! Is there a way to specify the order of the x-axis and y-axis labels? For example, if I wanted to have “Ford” to be at the top of the y-axis (instead of “Mercedes”)and “MPG” to be in the middle of the x-axis (instead of “Speed”)? Or, does create_annotated_heatmap() render the heat map based on the output of the pivot table?

Glad it worked! And right, the pandas pivot_table sorts alphabetically. The heat map will display what’s in the df, so just re-order how you want to appear.

Here’s one way to do it:

df = df.reindex(["Mercedes", "Buick", "Ford"], columns=["Speed", "MPG", "Styling"])

Thank you again, @AnnMarieW. This solves my problem!