What is the best way to use Dash with Websockets to build a real-time dashboard ? I would like to update a graph everytime a message is received but the only thing I've found is calling the callback every x seconds like the example below.
import dash
import dash_core_components as dcc
import dash_html_components as html
import dash_daq as daq
from dash.dependencies import Input, Output
import plotly
import plotly.graph_objs as go
from websocket import create_connection
from tinydb import TinyDB, Query
import json
import ssl
# Setting up the websocket and the necessary web handles
ws = create_connection(address, sslopt={"cert_reqs": ssl.CERT_NONE})
app = dash.Dash(__name__)
app.layout = html.Div(
[
dcc.Graph(id='live-graph', animate=True),
dcc.Interval(
id='graph-update',
interval=1*1000,
n_intervals=0)
]
)
@app.callback(Output('live-graph', 'figure'),
[Input('graph-update', 'n_intervals')])
def update_graph_live(n):
message = ws.recv()
x=message.get('data1')
y=message.get('data2')
.....
fig = go.Figure(
data = [go.Bar(x=x,y=y)],
layout=go.Layout(
title=go.layout.Title(text="Bar Chart")
)
)
)
return fig
if __name__ == '__main__':
app.run_server(debug=True)
Is there a way to trigger the callback everytime a message is received (maybe storing them in a database before) ?
You could have a look at the Websocket component from the Dash Extensions package. As you can see at the example, the package provides a WebSocket component that is included in your app's layout. Messages can be received in callbacks by the message property of WebSocket.
Regarding this, the solution to your problem would be like:
from dash_extensions import WebSocket
from dash_extensions.enrich import callback, dcc, html, Input, Output, DashProxy
# all dash imports are replaced by dash_extensions
import plotly.graph_objs as go
app = DashProxy(__name__)
app.layout = html.Div(
[
dcc.Graph(id='live-graph', animate=True),
WebSocket(id='ws', url="ws:...") # Websocket address is inserted here
]
)
@callback(Output('live-graph', 'figure'),
Input('ws', 'message'))
def update_graph_live(msg):
# Parsing msg depends on its structure, e.g.:
x = msg['x']
y = msg['y']
fig = go.Figure(
data=[go.Bar(x=x,y=y)],
layout=go.Layout(
title=go.layout.Title(text="Bar Chart")
)
)
return fig
The link above delivers further details about this topic, e.g. about the websocket setup.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With