1
votes

how can I make a real-time live update graph with multiple traces in it? For every time interval, i need to read line from “tmp.txt” to data[‘prof’] and data [‘pred’] and update in the line graph.

I found the solution for live-updating here (https://pythonprogramming.net/live-graphs-data-visualization-application-dash-python-tutorial/) but it does not show how to @app.callback for multiple traces. Also I found out that it uses “Event” which is outdated.

My coding is as follow, appreciate if someone can help me. Thanks.

import dash
import dash_daq as daq
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
from collections import deque

def read():
    with open ("tmp.txt", "r") as f:
        for line in f:
            data=line.split(',')
    return data 

i=0

data =  { 'prof':deque(maxlen=120), 'pred': deque(maxlen=120) }

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

app.layout = html.Div(

        children=[
            dcc.Interval(id='timer', interval=1000),
            html.Br(),
            html.Div([  
                dcc.Graph(id='graph')
                ])
            ])

@app.callback(Output('graph','figure'), [Input('timer','n_intervals')])
def update_graph():
    data=read()
    data=read()
    X.append(i)
    data['prof'].append(float(data[1]))
    data['pred'].append(float(data[2]))

    figure={
        'data':[
            {'x':X,'y':CPU['prof'],'type':'scatter','name':'Profiled'},
            {'x':X,'y':CPU['pred'],'type':'scatter','name':'Predicted'}
            ]}
    i+=1
    return figure

Edit: 'tmp.txt' is a file constantly overwritten by another program. It only has one line like below: '3.2233 4.33445', 32, 74.0, 0.13, 0.0, 0.0

1
Do you mind to provide a full mcve? In particular tmp.txt.rpanai
It lloks to me that you youtr tmp.txt can be read with pandas.rpanai
Hi, thank you for the reply. Please refer to the edited part. Hoo

1 Answers

1
votes

After trial and error, finally I came up with a solution using plotly.graph_objs:

   ....
   dcc.Interval(id='timer', interval=1000),
   html.Div([
            dcc.Graph(id='graph', animate=True),
            ], 
    ....

as for the callback:

@app.callback(Output('graph', 'figure'),
    [Input('timer', 'n_intervals')])
def update_graph_scatter(n):
    data=read()
    X.append(X[-1]+1)
    data['prof'].append(float(data[1]))
    data['pred'].append(float(data[2]))

    data = [go.Scatter(
            x=list(X),
            y=list(CPU['prof']),
            name='Prof',
            mode= 'lines+markers'
            ),
            go.Scatter(
            x=list(X),
            y=list(data['pred']),
            name='Pred',
            mode= 'lines+markers'
            ),
            ]

    return {'data': data,'layout' : go.Layout(xaxis=dict(range=[min(X),max(X)]),
                                                yaxis=dict(range=[0,380]))}