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