Real time graphs, adding other line on same graph

Hi Team!

Just want to ask how could it be possible to add more lines to this same graph using a real time graph through animate. I successfully had this script running but in order to add another line I think I need to create a figure, however, the return of the update_graph function doesn’t allow me to mention the “figure” variable so I would be able to add more lines to the same graph.

Any idea on how to modify this code?

import dash
from dash.dependencies import Output, Input
import dash_core_components as dcc
import dash_html_components as html
import plotly
import plotly.graph_objs as go

import random

X = []; X.append(0)
Y = []; Y.append(1)

app = dash.Dash(__name__)

app.layout = html.Div(children=[
    html.H1(children='Ejemplo grafica'),
    dcc.Graph(id='live-graph', animate=True),
    dcc.Interval(
        id='graph-update',
        interval=1000
        ),
    ]
)

@app.callback(Output('live-graph', 'figure'),
              [Input('graph-update', 'n_intervals')])

def update_graph(input_data):
    X.append(X[-1]+1)
    Y.append(Y[-1]+Y[-1]*random.uniform(-0.1,0.1))

# Here is where I define my graph...
    data = go.Scatter(
            x=list(X),
            y=list(Y),
            name='Scatter',
            mode= 'lines'
            )

# The return part only allows me to put the "data" variable as go.Scatter
    return {'data' : [data],
            'layout' : go.Layout(
                xaxis=dict(range=[X[0],X[-1]]),
                yaxis=dict(range=[min(Y)-0.1,max(Y)+0.1]),)
            }

if __name__ == '__main__':
    app.run_server(host='127.0.0.1', port=8080 ,debug=True)

I was able to create a “new variable” to add it in the return parameters, however I imagine there must be another “less messy way” to do this, specially because I need to add some vertical lines on a similar graph and this code looks really messy for that.

    data1 = go.Scatter(
        x=list(x),
        y=list(y_1),
        name='Sensor 1',
        mode= 'lines'
    )

    data1a = go.Scatter(
        x=list(x),
        y=list(y_2),
        name='Sensor 2',
        mode= 'lines'
    )

# ------ Some more code here --------

return {'data' : [data1, data1a],    # Adding the "new line in same graph"
            'layout' : go.Layout(
                xaxis=dict(range=[X[0],X[-1]]),
                yaxis=dict(range=[min(Y)-0.1,max(Y)+0.1]),)
            }

Thank you heaps!

You can use the go.Figure() method to create the figure and then use fig.add_trace() to add any n traces to your figure.

import dash
from dash.dependencies import Output, Input
import dash_core_components as dcc
import dash_html_components as html
import plotly
import plotly.graph_objs as go

import random

X = []; X.append(0)
Y = []; Y.append(1)
X2 = []; X2.append(0.2)
Y2 = []; Y2.append(1.2)

app = dash.Dash(__name__)

app.layout = html.Div(children=[
    html.H1(children='Ejemplo grafica'),
    dcc.Graph(id='live-graph', animate=True),
    dcc.Interval(
        id='graph-update',
        interval=1000
        ),
    ]
)

@app.callback(Output('live-graph', 'figure'),
              [Input('graph-update', 'n_intervals')])

def update_graph(input_data):
    X.append(X[-1]+1)
    Y.append(Y[-1]+Y[-1]*random.uniform(-0.1,0.1))
    X2.append(X2[-1]+1)
    Y2.append(Y2[-1]+Y2[-1]*random.uniform(-0.1,0.1))

    # Figure
    fig = go.Figure()
    fig.add_trace(
        go.Scatter(x=list(X), y=list(Y), name='Sensor 1', mode='lines')
    )
    fig.add_trace(
        go.Scatter(x=list(X2), y=list(Y2), name='Sensor 2', mode='lines')
    )
    fig.update_layout(xaxis=dict(range=[X[0],X2[-1]]), yaxis=dict(range=[min(Y)-0.3,max(Y2)+0.1]))

    return fig

if __name__ == '__main__':
    app.run_server(host='127.0.0.1', port=8080 ,debug=True)

Or you can create a function to add a new trace and then make a function call for adding each new line.
Like this:

fig = go.Figure()
def add_lines(x,y,name):
    fig.add_trace(
        go.Scatter(x=list(x), y=list(y), name=name, mode='lines'))

add_lines(X,Y,'Sensor 1')
add_lines(X2,Y2,'Sensor 2')
fig.update_layout(xaxis=dict(range=[X[0],X2[-1]]), yaxis=dict(range=[min(Y)-0.3,max(Y2)+0.1]))

return fig

Amazing @atharvakatre !

It worked perfectly. Thanks heaps!

1 Like