Black Lives Matter. Please consider donating to Black Girls Code today.
Dash HoloViews is now available! Check out the docs.

App with Interactive buttons and Dropdown menu

I am trying to build a Dash app that will support both a drop down menu for each of NY’s 27 districts as well as an interactive bar chart. The dataframe looks like this:

enter image description here

I have written the following code:

import dash
import dash_core_components as dcc
import dash_html_components as html
import plotly.graph_objs as go
import pandas as pd

# Read in the data 
df = districts_change.drop(['TOTAL'], axis=1)

# Get a list of all the districts
districts = districts_change['DISTRICT'].unique()

# Create the app
app = dash.Dash()

# Populate the layout with HTML and graph components
app.layout = html.Div([
    html.H2("New York Congressional Districts"),
    html.Div(
        [
            dcc.Dropdown(
                id="DISTRICT",
                options=[{
                    'label': i,
                    'value': i
                } for i in districts],
                value='All Districts'),
        ],
        style={'width': '25%',
               'display': 'inline-block'}),
    dcc.Graph(id='funnel-graph'),
])


# Add the callbacks to support the interactive componets
@app.callback(
    dash.dependencies.Output('funnel-graph', 'figure'),
    [dash.dependencies.Input('DISTRICT', 'value')])
def update_graph(Districts):
    if Districts == "All Districts":
        df_plot = df.copy()
    else:
        df_plot = df[df['DISTRICT'] == Districts]

    trace1 = go.Bar(x=districts_change['Year'], y=districts_change[('DEM')], name='DEM')
    trace2 = go.Bar(x=districts_change['Year'], y=districts_change[('REP')], name='REP')
    trace3 = go.Bar(x=districts_change['Year'], y=districts_change[('CON')], name='CON')
    trace4 = go.Bar(x=districts_change['Year'], y=districts_change[('WOR')], name='WOR')
    trace5 = go.Bar(x=districts_change['Year'], y=districts_change[('IND')], name='IND')
    trace6 = go.Bar(x=districts_change['Year'], y=districts_change[('GRE')], name='GRE')
    trace7 = go.Bar(x=districts_change['Year'], y=districts_change[('WEP')], name='WEP')
    trace8 = go.Bar(x=districts_change['Year'], y=districts_change[('REF')], name='REF')
    trace9 = go.Bar(x=districts_change['Year'], y=districts_change[('OTH')], name='OTH')
    trace10 = go.Bar(x=districts_change['Year'], y=districts_change[('BLANK')], name='BLANK')


    return {
        'data': [trace1, trace2, trace3, trace4, trace5, 
                     trace6, trace7, trace8, trace9, trace10],
        'layout':
        go.Layout(
            title='District {}'.format(Districts),
            barmode='group')
    }


if __name__ == '__main__':
    app.server.run(port=8000, host='127.0.0.1')

The app runs locally and displays the drop down menu, however, it is broadcasting the same data 27 times instead of the data that is unique to each district.

You created the new dataframe df_plot which is/should be unique to each district but you do not use this dataframe when creating the traces. You seem to be using the districts_change dataframe which im guessing contains the data for all districts.

Hi Mike - thanks for your reply. I see what you’re saying, do you have a suggestion for how to fix it? I’m a little confused as to how to incorporate all of the elements in concert. This is my first time using Dash.

If I understand correctly you just need to use the correct dataframe in the plot:

@app.callback(
    dash.dependencies.Output('funnel-graph', 'figure'),
    [dash.dependencies.Input('DISTRICT', 'value')])
def update_graph(Districts):
    if Districts == "All Districts":
        df_plot = df.copy()
    else:
        df_plot = df[df['DISTRICT'] == Districts]

    trace1 = go.Bar(x=df_plot ['Year'], y=df_plot [('DEM')], name='DEM')
    trace2 = go.Bar(x=df_plot ['Year'], y=df_plot [('REP')], name='REP')
    trace3 = go.Bar(x=df_plot ['Year'], y=df_plot [('CON')], name='CON')
    trace4 = go.Bar(x=df_plot ['Year'], y=df_plot [('WOR')], name='WOR')
    trace5 = go.Bar(x=df_plot ['Year'], y=df_plot [('IND')], name='IND')
    trace6 = go.Bar(x=df_plot ['Year'], y=df_plot [('GRE')], name='GRE')
    trace7 = go.Bar(x=df_plot ['Year'], y=df_plot [('WEP')], name='WEP')
    trace8 = go.Bar(x=df_plot ['Year'], y=df_plot [('REF')], name='REF')
    trace9 = go.Bar(x=df_plot ['Year'], y=df_plot [('OTH')], name='OTH')
    trace10 = go.Bar(x=df_plot ['Year'], y=df_plot [('BLANK')], name='BLANK')


    return {
        'data': [trace1, trace2, trace3, trace4, trace5, 
                     trace6, trace7, trace8, trace9, trace10],
        'layout':
        go.Layout(
            title='District {}'.format(Districts),
            barmode='group')
    }


if __name__ == '__main__':
    app.server.run(port=8000, host='127.0.0.1')

Yes, that did it! Thank you!

1 Like