✊🏿 Black Lives Matter. Please consider donating to Black Girls Code today.
🐇 Announcing Dash VTK for 3d simulation graphics. Check out the March webinar.

Mixing n_intervals with other inputs for multiple outputs in plotly dash

I am trying to create a near real-time dashboard that updates every 1 min or less. my data is from a database and i created a connection and queried the data in a pandas df before creating the layouts and the callbacks.

I use the data to create my radio-item,drop-downs as inputs, and to visualize the the data in graphs as outputs. the problem happens when I try to add the live-update component. I cant have the callback update the data before the layout, so I need to make it update every component I have in the layout. Makes a spaghetti code but I can manage to do that. My concern is I couldn’t find any examples where the output of a component has multiple Inputs including the n_intervals and other filtering components.

Here’s app code:

app = dash.Dash()    
    conn = pyodbc.connect("DRIVER={SQL Server};SERVER=IP;UID=username;PWD=password;DATABASE=master")
        q = open('main.sql',mode='r',encoding='utf-8-sig').read()
        results = pd.read_sql(q,conn)
        results.created_at = pd.to_datetime(results.created_at)

        app.layout(html.Div([
                    html.Div([ #row1 eight columns
                        html.Div([ #container-display
                                html.Div([
                                        html.H6('Region'),
                                        html.H5(id='region-card')
                                    ],className='mini_container')
                                html.Div([
                                        html.H6('Latest Update'),
                                        html.H5(id='date-card')
                                    ],className='mini_container')
                       ],className='row flex-display',style={'margin':'0.5%'}),
    html.Div([
        html.Div([
             html.Div(
                     [dcc.Dropdown(id='mapstyle',
                       options=[{'label':i,'value':i} for i in map_styles],
                       value='light',style={'width':'50%'}),
                     dcc.Graph(id='scattermap'),
                     dcc.Interval(id='data-update',interval=30*1000,n_intervals=0)
                     ],className='pretty_container')
                 ],className='eight columns'),


                    html.Div([
                        html.Div([
                             html.H3('Filters'),
                             html.Div([
                                  html.Div([
                                      html.Label('filter1'),
                                      html.Div([dcc.RadioItems(id='radio1',
                                                 options=[{'label': i, 'value': str(i)} for i in 
                                                 results.inside.unique())],value='All')
                                               ],className='six columns'),
                                    html.Div([
                            html.Div(html.Label('Region'),style={'width':'20%'}),
                            html.Div([dcc.Dropdown(id='drop1',
                                        options=[{'label': i , 'value': i } for i in 
                                        results.region_en.unique())],
                                        value='All',multi=True)])
                                            ])
                                           ],className='pretty_container'),
                        html.Div([
                                 dcc.Graph(id='bar')])
                                ],className='pretty_container')
                                ],className='four columns')
             ],className='row flex-display')

An here’s my callback:

             [Input('data-update','n_intervals'),
              Input('radio1','value'),
              Input('drop1','value'),
              Input('mapstyle','value')])

def update_map(n,radio1,drop1,value):
    results = pd.read_sql(q,conn)
    results.created_at = pd.to_datetime(results.created_at)
    df = results[results.created_at.map(lambda x: x.date()) == datetime.strptime(date, '%Y-%m-%d').date()].copy()
    if region == 'All' or (type(region) == list and ('All' in region or len(drop1) > 1)):
        layout_map = some_layout
    if 'All' not in region and len(region) == 1:
        df = df[df.region_en.isin(region)]
        layout_map = some_other_layout

    return {'data':[go.Scattermapbox(lat=df['lat'],lon=df['long'])],
             'layout':layout_map}

if __name__ == '__main__':
    app.run_server(debug=True)

The intervals doesn’t reproduce an error until i change the other inputs (radio, drop-down, etc) in a non-consistent way

My questions is: whats the best practice in mixing interval updates with other inputs for multiple outputs, andd is there a way or a shortcut to just update the data i queried before the app layout?

P.S. I deleted some components to make the code short so I might have some missing parenthesis