veg2020
veg2020

Reputation: 1020

Problem with callback error during Dash app implementation

I am trying to set up a simple Dash app that returns a value from a dataframe used as a "look-up table"; a screenshot of a sample test table is included hereenter image description here

Within the app, a user can enter one of many states (this is the first column in above table), and the app should return the corresponding two column entries from same row in which the state exists in this dataframe. For example: if a user selected LA, the app should return "med" and "radio"

Unfortunately, I am getting a call-back error after a user selection. My code is attached below. Can somebody please guide me on the way to resolve this? This is my first time using Dash - so appreciate any guidance!

app = dash.Dash(__name__)
server = app.server

df=pd.read_csv("test_lookup_table.csv", delimiter=',', encoding="utf-8-sig")
df.set_index('state')

app.layout = html.Div([
    html.H1('On demand look up '),
    html.H3('Select from list of states below'),
    dcc.Dropdown(
        id='dropdown',
        options=[{'label': i, 'value': i} for i in df.state],
        value='LALA'
    ),
    html.Div(id='display-value')
])


@app.callback(
    Output('dropdown','options'),
    [Input('dropdown', 'value')])


def callback_a(i):
    return df.loc[i, 1:3]

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

Upvotes: 1

Views: 7468

Answers (1)

coralvanda
coralvanda

Reputation: 6596

You did not mention the specific error, but I think I can see the problem. Your callback is outputing (Output) to the dropdown component's options prop. It sounds like you would want to output to something else, like a div or p component. You have a display-value ID for one div, so maybe that's where you want it to go? Try changing your callback like this:

@app.callback(
    Output('display-value', 'children'),
    [Input('dropdown', 'value')])
def callback_a(i):
    return df.loc[i, 1:3]

EDIT:

One problem is coming from setting the index to use the state column values. set_index returns a value, but you haven't assigned it, so nothing ends up happening. Use df = df.set_index('state') or include the inplace=True flag inside the method call.

That is causing the key error, because the df doesn't have the state values as indices, so you can't look for them. Now you can use df.loc[i] in your callback and it will be able to find the right row. You cannot use [1:3] here, though, because loc references by name, not value of the row/col, and you have no columns named with integers. You could do df.loc[i].tolist()[1:3]. However, with state as an index, you only have two values in each row (indices 0 and 1), so the :3] part is never going to get anything. You'll just get what's at index 1.

Lastly, and I should have mentioned this before, you've got the df set up as a global variable, which is generally not best practice. It would be better to use a callback to load the df in from your CSV file and add it to some component, like a dash_table.DataTable. Then you can have other callbacks pull values from that table instead of referencing a global variable.

Upvotes: 3

Related Questions