eliteA92
eliteA92

Reputation: 421

Plotly's Heatmap from (x, y, z) data

I am trying to achieve a Plotly's Heatmap. You can check the documentation in https://plotly.com/python/heatmaps/

One of the examples in the documentation is:

import plotly.graph_objects as go

fig = go.Figure(data=go.Heatmap(
                   z=[[1, None, 30, 50, 1], [20, 1, 60, 80, 30], [30, 60, 1, -10, 20]],
                   x=['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'],
                   y=['Morning', 'Afternoon', 'Evening'],
                   hoverongaps = False))
fig.show()

output: enter image description here

The problem is, let's say I have the data in an (x, y, z) like table. For example, accordingly to the plot above:

data = [
['Monday', 'Morning', 1],
['Monday', 'Afternoon', 20],
['Monday', 'Evening', 30],
['Tuesday', 'Morning', None],
['Tuesday', 'Afternoon', 1],
['Tuesday', 'Evening', 60],
['Wednesday', 'Morning', 30],
['Wednesday', 'Afternoon', 60],
['Wednesday', 'Evening', 1],
['Thursday', 'Morning', 50],
['Thursday', 'Afternoon', 80],
['Thursday', 'Evening', -10],
['Friday', 'Morning', 1],
['Friday', 'Afternoon', 30],
['Friday', 'Evening', 20]
]

or in a DataFrame:

import pandas as pd
df = pd.DataFrame(data=data, columns=['x','y','z'])
print(df)

output:

            x          y     z
0      Monday    Morning   1.0
1      Monday  Afternoon  20.0
2      Monday    Evening  30.0
3     Tuesday    Morning   NaN
4     Tuesday  Afternoon   1.0
5     Tuesday    Evening  60.0
6   Wednesday    Morning  30.0
7   Wednesday  Afternoon  60.0
8   Wednesday    Evening   1.0
9    Thursday    Morning  50.0
10   Thursday  Afternoon  80.0
11   Thursday    Evening -10.0
12     Friday    Morning   1.0
13     Friday  Afternoon  30.0
14     Friday    Evening  20.0

How can I easily transform this data to Plotly's required format?

Upvotes: 1

Views: 2574

Answers (1)

K.Cl
K.Cl

Reputation: 1783

Well, I must admit, this is not my cleanest code, but it got the job done.

First, notice how z in data has a different order from the plotly example z. This is because yours is sorted by day, and theirs is sorted by time of day. So first I sorted using that, with a custom dictionary key, used numpy's reshape method to get it into the required shape, then converted the values to floats.

For x and y, I used list comprehensions, the list-set trick, then sorted them back to the desired order.

Last, it's just a matter of plotting.

import plotly.graph_objects as go
import numpy as np

data = [
['Monday', 'Morning', 1],
['Monday', 'Afternoon', 20],
['Monday', 'Evening', 30],
['Tuesday', 'Morning', None],
['Tuesday', 'Afternoon', 1],
['Tuesday', 'Evening', 60],
['Wednesday', 'Morning', 30],
['Wednesday', 'Afternoon', 60],
['Wednesday', 'Evening', 1],
['Thursday', 'Morning', 50],
['Thursday', 'Afternoon', 80],
['Thursday', 'Evening', -10],
['Friday', 'Morning', 1],
['Friday', 'Afternoon', 30],
['Friday', 'Evening', 20]
]


seq_time = {'Morning':0, 'Afternoon':1, 'Evening':2}
seq_day = {'Monday':0, 'Tuesday': 1, 'Wednesday':2, 'Thursday':3, 'Friday':4}
data.sort(key = lambda x: seq_time[x[1]])
z = np.array([i[2] for i in data]).reshape(3,5).astype(float)
x = sorted(list(set([i[0] for i in data])), key = lambda x: seq_day[x])
y = sorted(list(set([i[1] for i in data])), key = lambda x: seq_time[x])

fig = go.Figure(data=go.Heatmap(
                   z=z,
                   x=x,
                   y=y,
                   hoverongaps = False))
fig.show()

Upvotes: 2

Related Questions