I'm building an interactive plot with the code below: everything works fine, except that Plotly refreshes the figure every time I change a property. So when I move the slider by one tick, Plotly refreshes the figure 4 times, which is annoying to see.
Is there a way to ask Plotly to only refresh the figure at the end of the update
function?
import numpy as np
import plotly.graph_objects as go
import panel as pn
pn.extension("plotly")
color_func = lambda x, y, z: x * y
f = lambda r, d: 10 * np.cos(r) * np.exp(-r * d)
x, y = np.mgrid[-7:7:100j, -7:7:100j]
r = np.sqrt(x**2 + y**2)
z = f(r, 0.1)
surfacecolor = color_func(x, y, z)
fig = go.Figure([
go.Surface(x=x, y=y, z=z, surfacecolor=surfacecolor, cmin=surfacecolor.min(), cmax=surfacecolor.max())
])
fig.update_layout({"scene": {"aspectmode": "cube"}})
slider = pn.widgets.FloatSlider(start=0, end=1, value=0.1)
@pn.depends(slider)
def update(d):
surfacecolor = color_func(d * x, y, z)
fig.data[0]["z"] = f(r, d)
fig.data[0]["surfacecolor"] = surfacecolor
fig.data[0]["cmin"] = surfacecolor.min()
fig.data[0]["cmax"] = surfacecolor.max()
return fig
pn.Column(slider, update)
Turns out that I need to use panel's Plotly pane. Note that its constructor requires a dictionary with the keys
data, layout
. If you give it a Plotly figure it will work, but the update will be extremely slow and unreliable.So this is the correct way to achieve my goal. By executing this code, the update will be very fast in comparison to the original attempt.