Hi,
I’m trying to create a real-time data application to monitor sensors, by displaying the last 1000 data points with a 100ms refresh.
I’ve been able to create a Dash web app using the extendData
callback on a Scattergl
Plotly plot, but it uses 50% of my CPU.
I then created a Panel application, and the same graph uses less than 15% of my CPU with hvPlot
:
import json
import pandas as pd
import hvplot.streamz
import holoviews as hv
from panel.widgets import IntSlider
import requests
from streamz.dataframe import PeriodicDataFrame
import redis
import panel as pn
pn.extension(sizing_mode="stretch_width")
# Connect to Redis cache
r = redis.Redis()
# Set up callback with streaming data
def sin_data(**kwargs):
# Read the last element from the Redis list
data = r.lindex('random_sin', -1)
if data:
data = json.loads(data)
index = pd.to_datetime(data['timestamp'], unit='ms')
return pd.DataFrame({'var_0': data['var_0'],
'var_1': data['var_1'],
'var_2': data['var_2'],
'var_3': data['var_3'],
'var_4': data['var_4'],
'var_5': data['var_5'],
'var_6': data['var_6'],
'var_7': data['var_7']},
columns=['var_' + str(x) for x in range(8)], index=[index])
df_1 = PeriodicDataFrame(sin_data, interval='100ms')
# Declare plots
line_1 = df_1.hvplot(kind='line', value_label="Sin", width=1200)
hv.extension('bokeh')
hv.renderer('bokeh').theme = 'caliber'
controls = pn.WidgetBox('# Commandes',
...
)
#pn.Row(line_1, controls)
pn.template.FastListTemplate(
site="Panel",
title="PoC",
sidebar=[*controls],
main=[
"POC hvPlot, Bokeh, Panel",
line_1,
]
).servable();
Now, I would like to use Holoviews in a Dash app to see if I can have better performances than with Plotly, so I adapted my code:
import dash
from dash import html
import holoviews as hv
from holoviews.plotting.plotly.dash import to_dash
from holoviews.streams import Buffer
import json
import pandas as pd
import hvplot.streamz
from streamz.dataframe import PeriodicDataFrame
import redis
# Connect to Redis cache
r = redis.Redis()
# Set up callback with streaming data
def sin_data(**kwargs):
# Read the last element from the Redis list
data = r.lindex('random_sin', -1)
if data:
data = json.loads(data)
index = pd.to_datetime(data['timestamp'], unit='ms')
return pd.DataFrame({'var_0': data['var_0'],
'var_1': data['var_1'],
'var_2': data['var_2'],
'var_3': data['var_3'],
'var_4': data['var_4'],
'var_5': data['var_5'],
'var_6': data['var_6'],
'var_7': data['var_7']},
columns=['var_' + str(x) for x in range(8)], index=[index])
df = PeriodicDataFrame(sin_data, interval='100ms')
# Declare plot
line = hv.DynamicMap(hv.Curve, streams=[Buffer(df)])
app = dash.Dash(__name__)
components = to_dash(app, [line])
app.layout = html.Div(components.children)
if __name__ == "__main__":
app.run_server(debug=True)
But there’s only one data point from var_0
showing in the plot:
What am I doing wrong here ?
Thanks in advance!