illuminato
illuminato

Reputation: 1247

Plotly Dash: getting error when click "clear value"

I created bar plot with Plotly Dash. Everything works fine but when I click "clear value": enter image description here

I am getting the next error message:

    KeyError: ('Quantity', 'declined')
    Traceback (most recent call last)
    File "C:\Users\iakubal\Anaconda3\envs\general_3_6\lib\site-packages\pandas\core\indexes\base.py", line 2646, in get_loc
    return self._engine.get_loc(key)
    File "pandas\_libs\index.pyx", line 111, in pandas._libs.index.IndexEngine.get_loc
    File "pandas\_libs\index.pyx", line 138, in pandas._libs.index.IndexEngine.get_loc
    File "pandas\_libs\hashtable_class_helper.pxi", line 1619, in pandas._libs.hashtable.PyObjectHashTable.get_item
    File "pandas\_libs\hashtable_class_helper.pxi", line 1627, in pandas._libs.hashtable.PyObjectHashTable.get_item
    During handling of the above exception, another exception occurred:
    File "pandas\_libs\index.pyx", line 701, in pandas._libs.index.BaseMultiIndexCodesEngine.get_loc
    File "C:\Users\iakubal\Anaconda3\envs\general_3_6\lib\site-packages\pandas\core\indexes\base.py", line 2648, in get_loc
    return self._engine.get_loc(self._maybe_cast_indexer(key))
    File "pandas\_libs\index.pyx", line 111, in pandas._libs.index.IndexEngine.get_loc
    File "pandas\_libs\index.pyx", line 138, in pandas._libs.index.IndexEngine.get_loc
    File "pandas\_libs\hashtable_class_helper.pxi", line 1619, in pandas._libs.hashtable.PyObjectHashTable.get_item
    File "pandas\_libs\hashtable_class_helper.pxi", line 1627, in pandas._libs.hashtable.PyObjectHashTable.get_item
    During handling of the above exception, another exception occurred:
    File "pandas\_libs\index.pyx", line 704, in pandas._libs.index.BaseMultiIndexCodesEngine.get_log
    KeyError: ('Quantity', 'declined')
Traceback (most recent call last):
  File "C:\Users\iakubal\Anaconda3\envs\general_3_6\lib\site-packages\pandas\core\indexes\base.py", line 2646, in get_loc
    return self._engine.get_loc(key)
  File "pandas\_libs\index.pyx", line 111, in pandas._libs.index.IndexEngine.get_loc
  File "pandas\_libs\index.pyx", line 138, in pandas._libs.index.IndexEngine.get_loc
  File "pandas\_libs\hashtable_class_helper.pxi", line 1619, in pandas._libs.hashtable.PyObjectHashTable.get_item
  File "pandas\_libs\hashtable_class_helper.pxi", line 1627, in pandas._libs.hashtable.PyObjectHashTable.get_item
KeyError: 'declined'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "pandas\_libs\index.pyx", line 701, in pandas._libs.index.BaseMultiIndexCodesEngine.get_loc
  File "C:\Users\iakubal\Anaconda3\envs\general_3_6\lib\site-packages\pandas\core\indexes\base.py", line 2648, in get_loc
    return self._engine.get_loc(self._maybe_cast_indexer(key))
  File "pandas\_libs\index.pyx", line 111, in pandas._libs.index.IndexEngine.get_loc
  File "pandas\_libs\index.pyx", line 138, in pandas._libs.index.IndexEngine.get_loc
  File "pandas\_libs\hashtable_class_helper.pxi", line 1619, in pandas._libs.hashtable.PyObjectHashTable.get_item
  File "pandas\_libs\hashtable_class_helper.pxi", line 1627, in pandas._libs.hashtable.PyObjectHashTable.get_item  
KeyError: 'declined'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "pandas\_libs\index.pyx", line 704, in pandas._libs.index.BaseMultiIndexCodesEngine.get_loc
KeyError: ('Quantity', 'declined')

Also, when I click to "clear value" it should show original plot, but it doesn't do it.

I tried to change a data-frame to another one but I am still getting the same error. It looks for me as there is some problem with Pandas. Here is reproducible code snippet (taken from here):

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 from Excel
df = pd.read_excel(
    "https://github.com/chris1610/pbpython/blob/master/data/salesfunnel.xlsx?raw=True"
)

# Get a list of all the avilable managers
mgr_options = df["Manager"].unique()

# Create the app
app = dash.Dash()

# Populate the layout with HTML and graph components
app.layout = html.Div([
    html.H2("Sales Funnel Report"),
    html.Div(
        [
            dcc.Dropdown(
                id="Manager",
                options=[{
                    'label': i,
                    'value': i
                } for i in mgr_options],
                value='All Managers'),
        ],
        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('Manager', 'value')])
def update_graph(Manager):
    if Manager == "All Managers":
        df_plot = df.copy()
    else:
        df_plot = df[df['Manager'] == Manager]

    pv = pd.pivot_table(
        df_plot,
        index=['Name'],
        columns=["Status"],
        values=['Quantity'],
        aggfunc=sum,
        fill_value=0)

    trace1 = go.Bar(x=pv.index, y=pv[('Quantity', 'declined')], name='Declined')
    trace2 = go.Bar(x=pv.index, y=pv[('Quantity', 'pending')], name='Pending')
    trace3 = go.Bar(x=pv.index, y=pv[('Quantity', 'presented')], name='Presented')
    trace4 = go.Bar(x=pv.index, y=pv[('Quantity', 'won')], name='Won')

    return {
        'data': [trace1, trace2, trace3, trace4],
        'layout':
        go.Layout(
            title='Customer Order Status for {}'.format(Manager),
            barmode='stack')
    }


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

Hope this snippet will help to find answer.

Upvotes: 0

Views: 302

Answers (1)

coralvanda
coralvanda

Reputation: 6596

You can just add something like this to the top of your callback func:

if Manager is None:
    raise dash.exceptions.PreventUpdate

edit: From the change to the original question, I believe this will give you the behavior you're looking for:

    if Manager == "All Managers" or Manager is None:
        df_plot = df.copy()
    else:
        df_plot = df[df['Manager'] == Manager]

This is a sort of tricky behavior for the user, because it's essentially hiding an option. It may be better to include this option (Manger == "All Managers") as one of the dropdown options, and then set the dropdown to have clearable=False.

Upvotes: 2

Related Questions