0

I'm trying to use Panel to plot live data in Python. The idea is that data arrives, which dictates the value of the timeslider widget, and this timeslider widget is used to interact with the plot showing live data. I'm using pn.add_period_callback to handle the automatic re-calling of the function.

In its reduced form, the code looks something like this:

from matplotlib.figure import Figure
from functools import partial
import numpy as np
import panel as pn
pn.extension()

# instantiate global plotting figures
fig = Figure(figsize=(8, 6))
ax = fig.subplots()
mpl_pane = pn.pane.Matplotlib(fig, dpi=144)

pn.state.cache['counter'] = 0

def plot(x,y,idx):
    # plot the noisy sine curve + include 
    # axvline to indicate what we're looking at
    ax.clear()
    ax.plot(x[:idx],y[:idx])
    ax.axvline(index)
    ax.set_title(f"Counter = {idx}")
    # overwrite mpl_pane object
    mpl_pane.object = fig
    return

def update(x,y):
    
    pn.state.cache['counter'] +=  1
    idx = pn.state.cache['counter']
    
    # simulate new live data arriving
    _x = float(idx) / np.pi
    _y = np.sin(_x) + (np.random.rand(1) - 0.5)
    
    # overwrite host dataset
    x[idx] = _x
    y[idx] = _y
    
    # define slider based on current array bounds
    slider = pn.widgets.DiscreteSlider(
        name='Scale', options=[i for i in range(0,idx)], value=idx
    )
    
    # link the timeslider with the plotting function
    iupdate = pn.bind(
        plot, x=x, y=y, idx=slider
    )
    
    iupdate()

    return pn.Column(slider, mpl_pane)

def panel_app():
    # define data being worked on
    N = 100
    x = np.empty(N)
    y = np.empty(N)
    
    # run the update periodically to check for any new data arriving and plot it
    cb = pn.state.add_periodic_callback(
        partial(update, x=x, y=y), period=2000, count=N, start=True
    )

    return

pn.serve(panel_app)

In this code I am attempting to plot a sine curve, whose next value is updated at each periodic callback. A widget is created at each callback that spans the length of the trace, and is used to create an axvline to display what index is being selected with the DiscreteSlider. However, this isn't plotting anything and is simply returning nothing to the screen. Does anyone have any ideas on how to make this work?

Thanks in advance!

0 Answers0