#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, и выпадающий список «Задание» не получал никаких данных из выпадающего списка «Округ». Штат и округ прекрасно общались друг с другом. Приношу свои извинения, если это отнимает у вас время. Я очень ценю помощь (вы серьезно помогли мне и по предыдущему вопросу).