Build slice by slice a heatmap

Hello,

I am trying to build slice by slice a heatmap. How can I update the data present in the graph without generating a full figure? The following code each time produces a new plot. I tried to use fig.update_traces() but it didn’t work.

What am I missing?

Thanks

import numpy as np
import plotly.express as px
import pandas as pd
import time
df = pd.DataFrame(np.random.rand(1,100))


for i in range(0,10):
    df = df.append(pd.DataFrame(np.random.rand(1,100)), ignore_index = True)
    time.sleep(1)
    fig = px.imshow(df)
    fig.show()

Hey @Fafou ,

I am not familiar with plotly express. I created go.Heatmap version. Maybe this could help.

import numpy as np
import plotly.express as px
import plotly.graph_objects as go
import pandas as pd
import time
df = pd.DataFrame(np.random.rand(1,100))


fig = go.Figure(go.Heatmap())

for i in range(0,10):
    df = df.append(pd.DataFrame(np.random.rand(1,100)), ignore_index = True)
    time.sleep(1)
    fig.add_trace(go.Heatmap(z=df))
fig.show()

1 Like

Hi Akroma,

Thanks for your answer. I tried this before and in this case, indeed a single plot is generated but only at the end with all the slices. What I would like is to see every second a new slice being added to the graph.

Hi @Fafou,

I animated the succesive heatmap slices. To get each slice of the same height I added a scatter chart (dummy trace) to the fig, that plots invisibly the diagonal oposite points of the layout.

import numpy as np
import plotly.graph_objects as go

N=225
n=15 #n=sqrt(N)
ez= np.random.rand(N).reshape((n, n))
updatemenus = [dict(
        buttons = [
            dict(
                args = [None, {"frame": {"duration": 500, "redraw": True},
                                "fromcurrent": True}],
                label = "Play",
                method = "animate"
                ),
            dict(
                 args = [[None], {"frame": {"duration": 0, "redraw": False},
                                  "mode": "immediate",
                                  "transition": {"duration": 0}}],
                label = "Pause",
                method = "animate"
                )
        ],
        showactive = False,
        type = "buttons",
        x = 1.05,
        xanchor = "left",
        y = 1,
        yanchor = "top"
    )]  

# scatter chart is a dummy trace to keep layout of constant height
fig=go.Figure(go.Scatter(x=[0, n-1], y=[0, n-1], mode="markers", marker_size=0.05)) 
fig.add_heatmap( z= ez[:1, :], showscale=False)
fig.update_layout( width=600, height=600,  
                  yaxis_autorange="reversed",
                  updatemenus=updatemenus)
frames=[go.Frame(data=[go.Heatmap(z=ez[:k+1, :])],
                traces=[1])    for k in range(n)]
fig.update(frames=frames);

fig.show()

Hi Empet,

Thanks a lot for your answer! It looks very good and actually the fact that you added the buttons will also help me a lot for what I want to do. The only remaining problem I have is I am fetching the database from a physical electronic instrument at every step. This means I don’t have the full dataset at start but I am “building it on the fly”. I tried a few things but didn’t manage to call a function (that would fetch the results) at each iteration. Would you know how to do it?

Thanks again for your reply!