Python heatmap appears empty

Hello,

I have a simple heatmap made from the many good examples you have. It reads some json file to get the values for the x, y and colorbar axis.

import plotly.graph_objs as go
import json
import pandas as pd
from collections import OrderedDict 

with open('swa-azimuth-timeseries.json', 'r') as f:
    json_file = json.load(f)

data = json_file['data']

epochs = list(map(int, [item[0] for item in data]))
azimuths = list(map(float, [item[2] for item in data]))
electrons = list(map(float, [item[4] for item in data]))   

epochs_as_string = [item[0] for item in data]
z_axis = [[float(item[4])] for item in data if item[0] in epochs_as_string]

bar = {
    'tick0': 0,
    'tickmode': 'array'
}   

color = (
        [0, "#00007F"],       
        [0.125, "#0000ff"], 
        [0.25, "#007FFF"], 
        [0.375, "#00ffff"],   
        [0.5, "#7FFF7F"],
        [0.625, "#ffff00"],       
        [0.75, "#FF7F00"],
        [0.875, "#ff0000"],
        [1, "#7F0000"])           


data = [go.Heatmap( x=epochs, y=azimuths, z=z_axis, colorscale=color, colorbar=bar)]
fig = go.Figure(data=data)

fig.update_layout(
    title = 'Time Series example'
)

print(fig)
fig.show()

I believe the figure is correct:

Figure({
    'data': [{'colorbar': {'tick0': 0, 'tickmode': 'array'},
              'colorscale': [[0, '#00007F'], [0.125, '#0000ff'], [0.25,
                             '#007FFF'], [0.375, '#00ffff'], [0.5, '#7FFF7F'],
                             [0.625, '#ffff00'], [0.75, '#FF7F00'], [0.875,
                             '#ff0000'], [1, '#7F0000']],
              'type': 'heatmap',
              'x': [63745131000000, 63745131000000, 63745131000000, ...,
                    63745142300000, 63745142300000, 63745142300000],
              'y': [5.625, 16.875, 28.125, ..., 331.875, 343.125, 354.375],
              'z': [[3981.9308143034305], [4695.791109174329],
                    [3234.6012850072925], ..., [2053.76027406144],
                    [2399.8534297886836], [4356.079470806262]]}],
    'layout': {'template': '...', 'title': {'text': 'Time Series example'}}
})

The JSON looks like this, very simple:

"data": [
    [
      "63745131000000",
      "-42.1875",
      "5.625",
      "1.06811",
      "3981.9308143034305"
    ],
    [
      "63745131000000",
      "-42.1875",
      "16.875",
      "1.06811",
      "4695.791109174329"
    ],
    [
      "63745131000000",
      "-42.1875",
      "28.125",
      "1.06811",
      "3234.6012850072925"
    ],
    [
      "63745131000000",
      "-42.1875",
      "39.375",
      "1.06811",
      "6389.844786765399"
    ],
    [
      "63745131000000",
      "-42.1875",
      "50.625",
      "1.06811",
      "6115.679777600199"
    ],
    [
      "63745131000000",
      "-42.1875",
      "61.875",
      "1.06811",
      "7486.080787986945"
    ],
    [
      "63745131000000",
      "-42.1875",
      "73.125",
      "1.06811",
      "4741.151907590278"
    ],
    [
      "63745131000000",
      "-42.1875",
      "84.375",
      "1.06811",
      "2059.7882348177613"
    ],
    [
      "63745131000000",
      "-42.1875",
      "95.625",
      "1.06811",
      "2566.031298380885"
    ],
    [
      "63745131000000",
      "-42.1875",
      "106.875",
      "1.06811",
      "3709.474486975868"
 ...

The z axis is a list of lists, it has all the values for a given epoch as you can see in the figure output.

When the plot is shown, it appears empty, even though it seems the axis are correct:

The idea I have is for epoch 1, there is an array of values which get plotted up this column on the y axis.

Any help would be appreciated. Perhaps the library is not sophisticated enough for this type of plotting?

Thanks

@jpcook

To get a heatmap your data should be defined as follows:

if x is a list of length n, y a list of length m, then z should be a list of lists, that converted to a numpy array, has the shape (m,n).
From your printed fig the list of lists z, does not meet this requirement.

@empet - thanks for the reply. But I have to pass a list of lists to z, right?.

It sounds like I might have it the wrong way around (n,m) instead of what you suggest. I will try that. Thanks again.

@jpcook I updated the above reply/comment and inserted list of lists. It was obviously that it should be a list of lists as long as its conversion to an array has the shape (m,n), with m, n>1. I stress that the number of y values gives the number of rows in z, and x values the number of columns.

Hello @empet ,

I tried again and it is nearly working
x length = 864
y length = 32

numpy array shape which matches.
(32, 864)

However when I set the x axis to the list with 864, nothing appears, but if I omit x it works but I would obviously want my own values on the x axis:

The x is a list of numbers like:
63745130500000, 63745130600000, 63745130700000, 63745130800000, 63745130900000

Maybe I can just somehow customize the label value from x and omit setting the values??

@jpcook

Once x and y are defined as lists, you have to associate a meshgrid:

x, y =np.meshgrid(x, y)

Now x and y have the shape of z,
and the heatmap is defined as follows:

heat = go.Heatmap(x=x, y=y, z=z, colorscale=color, ...).

Thanks @empet - I got it to work but by only supplying x from the meshgrid e.g)

x, y =np.meshgrid(epochs, azimuths)
data = [go.Heatmap(x=x, y=azimuths,z=rows1, colorscale=color)] 

If I supply y from the meshgrid, it does not work. I don’t really understand why.

Is there some way I can format the x axis, this numbers are an epoch time which have a way to convert to UTC. How could I implement that and only show a subset on the axis. Likewise with the colourbar to put the scale into a more scientific format?

Something like this is what I would like to do. Thanks again.