✊🏿 Black Lives Matter. Please consider donating to Black Girls Code today.
⚡️ Concerned about the grid? Kyle Baranko teaches how to predicting peak loads using XGBoost. Register for the August webinar!

Multiple users/browser tabs causing mixing of data on plots

I am creating an app in Django that uses Dash and Plotly components. To test some functionality, I dumbed the app down to a page that has a dropdown where a user chooses “latitude” or “longitude” and then the script calls an ISS location API that plots the latitude or longitude of the ISS depending on what the user chooses. This is a live plot that gets updated using dcc.Interval every 3 seconds. This works great, until I open two instances of the app in my browser. If the first browser tab has “latitude” and the second browser tab has “longitude” the plots will mix the data and bounce back and forth plotting both values. Has anybody ever run into this? The app I am creating is being deployed to AWS so multiple users need to be able to use it at once. I have been playing with clientside callbacks and some other things but I am not sure how to get it to not have this bug anymore. I will include the code and what the plot behavior looks like below.

data = deque(maxlen=30)
timeStamp = deque(maxlen=30)

liveOut = DjangoDash("LiveOutput")

liveOut.layout = html.Div([
            dcc.Dropdown(id='graph-indicator', style={'display': 'block'}, 
                        options=[
                            {'label':"latitude", 'value':"latitude"},
                            {'label':"longitude", 'value':"longitude"},
                        ],),
            dcc.Graph(id='graph', style={'width':'49%', 'display': 'inline-block'}),
            html.Div(style={'width':'1%', 'display': 'inline-block'}),
            html.Div(id='hidden-div', style={'display':'none'}),
            dcc.Interval(
                id='graph-update',
                interval=3000,
                n_intervals=0
            ),
        
])

@liveOut.callback(
    Output('hidden-div','value'),
    [Input('graph-indicator','value')],)
def clear_data(value):
    data.clear()
    timeStamp.clear()
    return "blank"

@liveOut.callback(
    Output('graph', 'figure'),
    [Input('graph-update', 'n_intervals'),
    Input('graph-indicator', 'value')],
)
def update_graph_scatter(n, dropdown_val):
    url = 'http://api.open-notify.org/iss-now.json'
    response_iss = requests.get(url)
    value_current = float(
        response_iss.json()['iss_position'][dropdown_val])
    timeStamp.append(datetime.now())
    data.append(value_current)

    trace1 = go.Scatter(
        x=list(timeStamp),
        y=list(data),
        name='value',
        mode='lines+markers'
    )

    plot1={
        'data': [trace1],
        'layout': go.Layout(
            xaxis=dict(range=[min(timeStamp), max(timeStamp)]),
            yaxis=dict(range=[-180, 180]),
            paper_bgcolor='#243a5c',
            plot_bgcolor='rgba(0,0,0,0)',
            font=dict(color='white'),
            title='Live ISS Location Plot',
        )
    }

    return plot1

LivePlot

After more searching around, I have decided to look into using the dcc.Store component and maybe a clientside callback. The issue that I’m struggling with is I’m not sure how to append data in a dcc.Store component. I only want to hold 30 data points in the array so I’m using a deque() and when the interval fires, I would like to call the API and append the data in the dcc.Store, then plot the data. Maybe there is a workaround for this?