Zach Cornelison
Zach Cornelison

Reputation: 67

Dash Interactive Graph Won't Update From Pandas Dataframe

I am trying to create a bar graph that updates from a multi-select drop-down menu on Dash but when I select an area code to graph, nothing changes.

My dataframe consists of about 11 rows with 4 columns:

  Zip Code  Area Name     percent no internet   Mean Income Past 12 Months
0   38126   South Forum   0.8308                26346
1   38106   South Memphis 0.8223                31403
2   38108   Hollywood     0.7356                31278

Here is the code for the callback:

@app.callback(
    dash.dependencies.Output('graph1', 'figure'),
    [dash.dependencies.Input('demo-dropdown', 'value')])
def update_image_src(selector):
    data = []
    filtered_data = df[df['Zip Code'] == zip_code]
    for zip_code in selector:
        data.append(dict(
            x=filtered_data['Area Name'][0],
            y=filtered_data['percent no internet'][0],
            type='bar',
            name=zip_code))
    figure = {
        'data': data,
        'layout': {
            'title': 'Percent of homes lacking broadband internet',
            'xaxis' : dict(
                title=data[0],
                titlefont=dict(
                family='Courier New, monospace',
                size=20,
                color='#7f7f7f'
            )),
            'yaxis' : dict(
                title='% No Internet',
                titlefont=dict(
                family='Helvetica, monospace',
                size=20,
                color='#7f7f7f'
            ))
        }
    }
    return figure

Upvotes: 2

Views: 1659

Answers (1)

Ben.T
Ben.T

Reputation: 29635

IIUC, here is a code that seem to do what you want. The point I can address with your original code is that first you don't define the type of graph, second instead of iterating over the selector, you can use isin to get all at once. Hope it will help you

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

# the few rows of your question
import pandas as pd
df = pd.DataFrame( {'Zip Code': {0: 38126, 1: 38106, 2: 38108},
                    'Area Name': {0: 'South Forum', 1: 'South Memphis', 2: 'Hollywood'},
                    'percent no internet': {0: 0.8308, 1: 0.8223, 2: 0.7356},
                    'Mean Income Past 12 Months': {0: 26346, 1: 31403, 2: 31278}})   
# main app
app = dash.Dash(__name__)
app.layout = html.Div(children=[
    dcc.Dropdown(
        id='demo-dropdown', 
        options=[
            {'label': 38126, 'value': 38126},
            {'label': 38106, 'value': 38106},
            {'label': 38108, 'value': 38108}
        ],
        value=[38126, 38106],
        multi=True
    ),
    dcc.Graph(id='graph1'),
])

@app.callback(
    dash.dependencies.Output('graph1', 'figure'),
    [dash.dependencies.Input('demo-dropdown', 'value')])
def update_image_src(selector):
    # instead of iterating, use isin to select all the zipcode from the dropdown
    filtered_data = df.loc[ df['Zip Code'].isin(selector), 
                            ['Area Name', 'percent no internet']]

    figure = {
        # in figure, see how the data is defined
        'data': [{'x': filtered_data['Area Name'], 
                  'y': filtered_data['percent no internet'], 
                  'type': 'bar'}
        ],
        'layout': {
            'title': 'Percent of homes lacking broadband internet',
            'xaxis' : dict(
                title='Area Name', #change this, I'm not sure what you wanted
                titlefont=dict(
                    family='Courier New, monospace',
                    size=20,
                    color='#7f7f7f'
                )
            ),
            'yaxis' : dict(
                title='% No Internet',
                titlefont=dict(
                    family='Helvetica, monospace',
                    size=20,
                    color='#7f7f7f'
                )
            )
        }
    }
    return figure


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

EDIT: to get different colors and the legend, then replace in the dictionnary figure with this:

figure = {
        # in figure, see how is define the data
        'data': [{'x': [area_name], 
                  'y': [percent], 
                  'type': 'bar', 
                  'name': area_name}
                  for area_name, percent in filtered_data.to_numpy()
        ],
...

Upvotes: 2

Related Questions