Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
holoviz
GitHub Repository: holoviz/panel
Path: blob/main/doc/how_to/callbacks/periodic.md
2012 views

Periodically Run Callbacks

This guide addresses how to set up per-session callbacks that run periodically.


Periodic callbacks allow periodically updating your application with new data. Below we will create a simple Bokeh plot and display it with Panel:

import numpy as np import panel as pn from bokeh.models import ColumnDataSource from bokeh.plotting import figure pn.extension() source = ColumnDataSource({"x": np.arange(10), "y": np.arange(10)}) p = figure() p.line(x="x", y="y", source=source) bokeh_pane = pn.pane.Bokeh(p) bokeh_pane.servable()

Now we will define a callback that updates the data on the ColumnDataSource and use the pn.state.add_periodic_callback method to schedule updates every 200 ms. We will also set a timeout of 5 seconds after which the callback will automatically stop.

The dynamic callbacks may not function properly in the online documentation. Please use them in a notebook or script.
def update(): data = np.random.randint(0, 2 ** 31, 10) source.data.update({"y": data}) bokeh_pane.param.trigger('object') # Only needed in notebook cb = pn.state.add_periodic_callback(update, 200, timeout=5000)

In a notebook or bokeh server context we should now see the plot update periodically. The other nice thing about this is that pn.state.add_periodic_callback returns PeriodicCallback we can call .stop() and .start() on if we want to stop or pause the periodic execution. Additionally we can also dynamically adjust the period by setting the timeout parameter to speed up or slow down the callback.

Other nice features on a periodic callback are the ability to check the number of executions using the cb.counter property and the ability to toggle the callback on and off simply by setting the running parameter. This makes it possible to link a widget to the running state:

toggle = pn.widgets.Toggle(name='Toggle callback', value=True) toggle.link(cb, bidirectional=True, value='running') toggle

Note that when starting a server dynamically with pn.serve you cannot start a periodic callback before the application is actually being served. Therefore you should create the application and start the callback in a wrapping function:

from functools import partial import numpy as np import panel as pn from bokeh.models import ColumnDataSource from bokeh.plotting import figure def update(source): data = np.random.randint(0, 2 ** 31, 10) source.data.update({"y": data}) def panel_app(): source = ColumnDataSource({"x": np.arange(10), "y": np.arange(10)}) p = figure() p.line(x="x", y="y", source=source) cb = pn.state.add_periodic_callback(partial(update, source), 200, timeout=5000) toggle = pn.widgets.Toggle(name='Toggle callback', value=True) toggle.link(cb, bidirectional=True, value='running') return pn.Column(pn.pane.Bokeh(p), toggle) pn.serve(panel_app)