Plotly Dash: цепные обратные вызовы работают нормально, но всегда выдают ValueError. Как исправить или отключить?

#pandas #plotly #plotly-dash

#pandas #plotly #plotly-dash

Вопрос:

У меня есть набор данных, в котором перечислены различные задания и какие инструменты необходимы по дате и местоположению. Вот крошечный пример моего df:

 State,County,Job,Tool,Start,End
LA,Acadia,A,Hammer,2020-10-19,2020-11-02
LA,Acadia,A,Drill,2020-11-02,2020-12-02
LA,Acadia,B,Hammer,2020-11-28,2020-12-30
LA,Orleans,A,Hammer,2020-10-03,2020-11-02
LA,Orleans,A,Drill,2020-11-05,2020-12-02
LA,Orleans,B,Hammer,2020-12-03,2020-12-30
TX,Travis,A,Hammer,2020-10-19,2020-11-02
TX,Travis,A,Drill,2020-11-02,2020-12-02
TX,Travis,B,Hammer,2020-11-28,2020-12-30
TX,Brazoria,A,Hammer,2020-10-03,2020-11-02
TX,Brazoria,A,Drill,2020-11-05,2020-12-02
TX,Brazoria,B,Hammer,2020-12-03,2020-12-30
 

Мои dcc.Dropdowns и dcc.RadioItems следующие:

         html.Div([
            html.Label("State:", style={'fontSize': 30, 'textAlign': 'center'}),
            dcc.Dropdown(
                id='state-dpdn',
                options=[{'label': s, 'value': s} for s in sorted(df.State.unique())],
                value='LA',
                clearable=False,
            )],
        html.Div([
            html.Label("County:", style={'fontSize': 30, 'textAlign': 'center'}),
            dcc.Dropdown(
                id='county-dpdn',
                options=[],
                value=[],
                clearable=False
            )],
        html.Div([
            html.Label("Job:", style={'fontSize': 30, 'textAlign': 'center'}),
            dcc.RadioItems(
                id='radio-buttons',
                options=[],
            ),
 

И вот мои обратные вызовы:

     @app.callback(
        Output('county-dpdn', 'options'),
        Output('county-dpdn', 'value'),
        Input('state-dpdn', 'value'),
    )
    def set_county_options(chosen_state):
        dff = df[df.State == chosen_state]
        counties_of_state = [{'label': c, 'value': c} for c in sorted(dff.County.unique())]
        values_selected = [x['value'] for x in counties_of_state]
        return counties_of_state, values_selected

    @app.callback(
        Output('radio-buttons', 'options'),
        Output('radio-buttons', 'value'),
        Input('county-dpdn', 'value'),
    )
    def set_job_options(chosen_county):
        dff = df[df.County == chosen_county] ###THIS IS LINE 255 W/ ERROR###
        job_of_county = [{'label': c, 'value': c} for c in dff.Job.unique()]
        values_selected = job_of_county[0]['value']
        return job_of_county, values_selected

    @app.callback(
        Output('graph1', 'children'),
        Input('radio-buttons', 'value'),
        Input('county-dpdn', 'value'),
        Input('state-dpdn', 'value')
    )
    def build_graph(job_selected, location_selected, state_selected):
        if isinstance(state_selected, str):
            df['State'].eq(state_selected)

        if isinstance(location_selected, str):
            df['County'].eq(location_selected)

        if isinstance(job_selected, str):
            df['Job'].eq(job_selected)

        dffgraph = df[df['State'].eq(state_selected) amp; df['County'].eq(location_selected) amp; df['Job'].eq(job_selected)]

        ###dffgraph manipulation and figure creation down here###

 

Все это работает, загружает данные по назначению, и мои графики великолепны. Моя проблема возникает при попытке донести это до пользователей без ошибок. Ошибки были полезны при построении всего, но когда пришло время настроить представление моих графиков, я отключил ошибки, чтобы вернуться к ним позже с помощью dev_tools:

 if __name__ == '__main__':
    app.run_server(debug=False, port=5000, dev_tools_ui=False, dev_tools_props_check=False)
 

Я создаю многостраничное приложение dash, которое отлично работает, но когда я помещаю этот код в свое основное многостраничное приложение или удаляю инструменты разработки из локального «app.run_server», показанного выше, я получаю следующую ошибку:

 File "/Users/Documents/pythonProject/app.py", line 255, in set_job_options
dff = df[df.County == chosen_county]
File "/Users/venv/lib/python3.7/site-packages/pandas/core/ops/common.py", line 65, in new_method
return method(self, other)
File "/Users/venv/lib/python3.7/site-packages/pandas/core/ops/__init__.py", line 370, in wrapper
res_values = comparison_op(lvalues, rvalues, op)
File "/Users/venv/lib/python3.7/site-packages/pandas/core/ops/array_ops.py", line 225, in comparison_op
"Lengths must match to compare", lvalues.shape, rvalues.shape
ValueError: ('Lengths must match to compare', (4781,), (64,))
 

CSV-файл, используемый для создания моего df, имеет длину 4781 строки, а 64 — это количество приходов в Луизиане, поэтому число имеет смысл.

Хотя игнорирование этой ошибки работало до сих пор, после нескольких недель попыток иногда разобраться в этом, я хотел бы получить помощь с этой ошибкой. Спасибо!

Редактировать 1

Для получения помощи в простом отключении ошибок лучше всего показать, как настроено мое приложение. У меня есть многостраничное приложение Flask, и мое приложение Dash вызывается, когда пользователь направляется к нему.

Мой dashboard.py файл выглядит следующим образом:

 def init_dashboard(server):
    """Create a Plotly Dash dashboard."""
    dash_app = dash.Dash(
        server=server,
        routes_pathname_prefix='/dashapp/',
        external_stylesheets=[dbc.themes.FLATLY]
    )

    # Load DataFrame
    df = create_dataframe()

    and so on....

    return dash_app.server
 

The init.py файл в моем приложении flask, который вызывает мой dashboard.py:

 def create_app(config_class=Config):
    app = Flask(__name__)
    app.config.from_object(config_class)

    .... all the normal init stuff ....

    from .plotlydash.dashboard import init_dashboard
    app = init_dashboard(app)

    return app
 

Перед развертыванием при тестировании моего приложения dash как единого объекта debug=False, dev_tools_ui=False, dev_tools_props_check=False все хорошо работают, чтобы отключить ошибки dash. Когда я помещаю свое рабочее приложение dash в свое приложение flask, как показано выше, оно по-прежнему работает нормально, но выдает ошибки, которые регистрируются и отправляются на мою электронную почту как сумасшедшие. Я попробовал несколько разных подходов к отключению только ошибок из моего приложения dash, но пока не нашел решения.

Комментарии:

1. Что, если вы попробуете dff = df.copy() , а затем dff = dff[dff.County == chosen_county] . То же самое для других, где вы берете кусочек df . Не уверен, что это может привести к появлению этого сообщения об ошибке plotly-dash .

2. Спасибо, но это не сработало. Обратные вызовы перестали функционировать.

Ответ №1:

Редактировать внизу.

Проблема в том, что вы делаете это:

dff = df[df.County == chosen_county]

но == он не будет работать со списком, а chosen_county является списком. Вы должны сделать

dff = df[df.County.isin(chosen_county)]

или требовать, чтобы было выбрано только одно значение, а не список.

Редактировать: чтобы сделать это с помощью выпадающего списка с одним значением, я думаю, правильным способом было бы:

dff = df[df['County'].eq(chosen_county)]

Выпадающий список не должен иметь multi=True , это было из моего предыдущего недоразумения. Пожалуйста, дайте мне знать, если это все еще не работает.

Комментарии:

1. Спасибо, но, к сожалению, это не сработало. Обратные вызовы перестали функционировать.

2. Выдает ли это ошибку? Что говорит об ошибке?

3. job_of_county = [{'label': c, 'value': c} for c in dff.Job.unique()] ^ SyntaxError: invalid syntax. . Стрелка указывает на y в графстве (трудно отформатировать в разделе комментариев). Интересно, что dff в dff = df[df.County == chosen_county] становится светло-серым при применении этого подхода .isin.

4. Работает ли это как df[df['County'].isin(chosen_county)] ?

5. Нет, я хочу, чтобы они выбирали только один штат и один округ одновременно. Тем не менее, я хочу, чтобы они могли выбирать несколько заданий из выбранного округа (используя radioitems для заполнения диаграммы планирования). Я только что попытался добавить multi=True, и выпадающий список «Задание» не получал никаких данных из выпадающего списка «Округ». Штат и округ прекрасно общались друг с другом. Приношу свои извинения, если это отнимает у вас время. Я очень ценю помощь (вы серьезно помогли мне и по предыдущему вопросу).