Plotly: best way to define the Z argument in the create_annotated_heatmap() function

Viewed 308

I'm brand new to Plotly and Dash. I'm trying to create a heat map that displays the underyling numerical values.

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 in the create_annotated_heatmap() function.

This is hacky. There has to be a better way!

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 agnostic and flexible as to what's being passed in)

Thanks!

1 Answers

It turns out that there is a much better (and less hacky) way! Courtesy of our friends at Plotly, the solution is 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']})

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()

Hope this helps someone in the future!

Related