Здравствуйте, я впервые работаю над приложением для черточки и не могу решить проблему, с которой сталкиваюсь.У меня есть интерфейс, который принимает пользовательский ввод, выполняет некоторые вычисления, сохраняет результат в скрытом div и затем обновляет график.
Приложение загружается нормально, однако сразу после нажатия кнопки «Отправить» возникает ошибка.Ниже приведен код, который я написал.Похоже, что обе функции обратного вызова запускаются одновременно.
app.layout = html.Div(style={'backgroundColor': colors['background']}, children=[
html.Div([
html.Div([
html.Img(src='data:image/png;base64,{}'.format(encoded_image.decode()), className="nine columns")
], className="three columns"),
html.Div([
html.Div([
html.Div([
html.P("Select Month Range:"),
],
className="two columns"
),
html.Div([
dcc.RangeSlider(
id='month_slider',
# updatemode='drag',
# count=1,
min=1,
max=maxmarks,
step=1,
value=[maxmarks - 1, maxmarks],
marks=tags,
pushable=1
),
],
className="six columns",
style={})
],
className="twelve columns",
style={
'backgroundColor': '#EFEAEA',
'padding-top': '1.5em',
'padding-bottom': '1em'
}),
html.Div([
html.Div([
dcc.Dropdown(
id='demographics',
options=[
{'label': 'All 18-49', 'value': '18-49'},
{'label': 'Female 25-54', 'value': '25-54F'},
{'label': 'All 25-54', 'value': '25-54'},
],
placeholder="Select Demographics",
)
],
className="two columns",
style={}),
html.Div([
dcc.Dropdown(
id='ID',
options=[
{'label': '200', 'value': 200, 'type': 'number'},
{'label': '250', 'value': 250, 'type': 'number'},
{'label': '300', 'value': 300, 'type': 'number'},
{'label': '350', 'value': 350, 'type': 'number'},
{'label': '400', 'value': 400, 'type': 'number'},
],
placeholder="Select ID",
)
],
className="two columns",
style={}),
html.Div([
dcc.Dropdown(
id='Income',
options=[
{'label': '50,000', 'value': 50000, 'type': 'number'},
{'label': '100,000', 'value': 100000, 'type': 'number'},
{'label': '200,000', 'value': 200000, 'type': 'number'},
{'label': '350,000', 'value': 350000, 'type': 'number'},
{'label': '500,000', 'value': 500000, 'type': 'number'},
],
placeholder="Select Income",
)
],
className="two columns",
style={}),
html.Div([
dcc.Dropdown(
id='Frquency',
options=[
{'label': 'None per week, 'value': 0, 'type': 'number'},
{'label': 'Once per Week', 'value': 1, 'type': 'number'},
{'label': 'Thrice per Week', 'value': 3, 'type': 'number'},
],
placeholder="Select Frequency",
)
],
className="two columns",
style={}),
html.Div([
html.Button('Submit', id='submit_button', className='twelve columns',
style={'background-color': '#2D91C3', 'color': 'white', 'font-size': '1em'})
],
className="two columns",
style={}),
],
className="twelve columns",
style={
'backgroundColor': '#EFEAEA',
'padding-top': '1em',
'padding-bottom': '1.5em'
})
], className="nine columns", style={})
], className="twelve columns"),
# dcc.graph layout
html.Div([
html.Div([
dcc.Graph(id='example-graph', config={"displayModeBar": False, "scrollZoom": False})
],
className="six columns",
style={'border-right': 'thin grey solid', 'border-left': 'thin grey solid',
'border-top': 'thin grey solid'}),
html.Div(id='intermediate-value1', style={'display': 'none'})
])]
@app.callback(
Output("intermediate-value1", "children"),
[Input("submit_button", "n_clicks")],
[
State("month_slider", "value"),
State("demographics", "value"),
State("Income", "value"),
State("Frequency", "value"),
],
)
def clean_data(n_clicks, month_range, demo, inc, fre_cap):
if n_clicks is not None and n_clicks > 0:
employee_data_temp = employee_data.copy()
start_date = month_range[0]
end_date = month_range[1]
mask1 = employee_data_temp["total_months"] == int(end_date - start_date)
employee_data_temp = employee_data_temp.loc[mask1]
mask2 = (
(employee_data_temp["demographic"] == demo)
& (employee_data_temp["freq_cap"] == fre_cap)
& (employee_data_temp["total_incressions"] == inc)
)
employee_data_temp = employee_data_temp.loc[mask2]
employee_data_temp = employee_data_temp.sort_values(by=["reach"])
employee_data_temp["income_percent"] = (employee_data_temp["reach"] / 955000) * 100
employee_data_temp = employee_data_temp.reset_index(drop=True)
return employee_data_temp.to_json(date_format="iso", orient="split")
else:
return []
@app.callback(Output("example-graph", "figure"),
[Input("submit_button", "n_clicks")],
[State("intermediate-value1", "children"),
State("Income", "value")])
def update_graph(n_clicks, employee_data_temp, inc):
t.sleep(2)
if n_clicks is not None and n_clicks > 0:
dff = pd.read_json(employee_data_temp, orient="split")
max_income = dff["income_percent"].iloc[9]
max_income = max_income.round(2)
trace = Scatter(
y=dff["income_percent"], x=dff["inc"], line=plotly.graph_objs.scatter.Line(color="#1a2d46"), mode="lines"
)
layout1 = Layout(
plot_bgcolor="#FFFFFF",
paper_bgcolor="#FFFFFF",
height=450,
title="Digital Reach - " + str(max_income) + " " + "%",
xaxis=dict(showgrid=True, showline=True, zeroline=True, fixedrange=True, title="Total Income"),
yaxis=dict(showline=True, fixedrange=True, zeroline=True, title="Income (%)"),
margin=plotly.graph_objs.layout.Margin(t=45, l=50, r=50),
)
return Figure(data=[trace], layout=layout1)
else:
return []
Ниже приводится ошибка, которую я получаю:
Traceback (most recent call last):
File "C:\Users\Tushar\Documents\django_projects\tvnz_dash_app\src\dash_app\incrementor\views.py", line 21, in dispatcher
response = server.full_dispatch_request()
File "C:\python37\lib\site-packages\flask\app.py", line 1815, in full_dispatch_request
rv = self.handle_user_exception(e)
File "C:\python37\lib\site-packages\flask\app.py", line 1718, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "C:\python37\lib\site-packages\flask\_compat.py", line 35, in reraise
raise value
File "C:\python37\lib\site-packages\flask\app.py", line 1813, in full_dispatch_request
rv = self.dispatch_request()
File "C:\python37\lib\site-packages\flask\app.py", line 1799, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "C:\python37\lib\site-packages\dash\dash.py", line 1073, in dispatch
response.set_data(self.callback_map[output]['callback'](*args))
File "C:\python37\lib\site-packages\dash\dash.py", line 969, in add_context
output_value = func(*args, **kwargs)
File "C:\Users\Tushar\Documents\django_projects\tvnz_dash_app\src\dash_app\incrementor\router.py", line 699, in update_graph
dff = pd.read_json(employee_data_temp, orient="split")
File "C:\python37\lib\site-packages\pandas\io\json\json.py", line 413, in read_json
path_or_buf, encoding=encoding, compression=compression,
File "C:\python37\lib\site-packages\pandas\io\common.py", line 232, in get_filepath_or_buffer
raise ValueError(msg.format(_type=type(filepath_or_buffer)))
ValueError: Invalid file path or buffer object type: <class 'NoneType'>
Я хочу, чтобы функция запускалась, когда пользовательнажмите кнопку отправки, и поскольку функция обновления графика зависит от функции очистки данных, она не должна запускаться до тех пор, пока функция очистки данных не будет завершена.
Пожалуйста, кто-нибудь может помочь мне понять, что мне не хватаетздесь и помогите решить проблему.
Заранее большое спасибо !!
НОВЫЕ ОБНОВЛЕННЫЕ ФУНКЦИИ
@app.callback(
Output("intermediate-value1", "children"),
[Input("submit_button", "n_clicks")],
[
State("month_slider", "value"),
State("demographics", "value"),
State("digital_impressions", "value"),
State("digital_frequency", "value"),
],
)
def get_match(n_clicks, month_range, demo, tarps):
if n_clicks is not None and n_clicks > 0:
some long python script data calculatation
return match_data_temp.to_json(date_format="iso", orient="split")
@app.callback(
Output("intermediate-value2", "children"),
[Input("submit_button", "n_clicks")],
[
State("month_slider", "value"),
State("demographics", "value"),
State("digital_impressions", "value"),
State("digital_frequency", "value"),
],
)
def clean_data(n_clicks, month_range, demo, inc, fre_cap):
if n_clicks is not None and n_clicks > 0:
employee_data_temp = employee_data.copy()
start_date = month_range[0]
end_date = month_range[1]
mask1 = employee_data_temp["total_months"] == int(end_date - start_date)
employee_data_temp = employee_data_temp.loc[mask1]
mask2 = (
(employee_data_temp["demographic"] == demo)
& (employee_data_temp["freq_cap"] == fre_cap)
& (employee_data_temp["total_incressions"] == inc)
)
employee_data_temp = employee_data_temp.loc[mask2]
employee_data_temp = employee_data_temp.sort_values(by=["reach"])
employee_data_temp["income_percent"] = (employee_data_temp["reach"] / 955000) * 100
employee_data_temp = employee_data_temp.reset_index(drop=True)
return employee_data_temp.to_json(date_format="iso", orient="split")
@app.callback(
Output("intermediate-value3", "children"),
[
Input("month_slider", "value"),
Input("demographics", "value"),
Input("intermediate-value2", "children"),
Input("intermediate-value1", "children"),
],
)
def get_match_overlap(month_range, demo, match_data_temp, employee_data_temp):
overlap_match = pd.read_json(match_data_temp, orient="split")
overlap_employee = pd.read_json(employee_data_temp, orient="split")
some long python calculatation
return final.to_json(date_format="iso", orient="split")
@app.callback(
Output("example-graph2", "figure"),
[Input("intermediate-value3", "children"), Input("intermediate-value2", "children")],
)
def update_graph(final, match_data_temp):
if final is not None:
dff_overlap = pd.read_json(final, orient="split")
dff_match_data = pd.read_json(match_data_temp, orient="split")
overlap = Scatter(
y=dff_overlap["final"],
x=dff_overlap["percentage"],
name="tile",
line=plotly.graph_objs.scatter.Line(color="red"),
mode="lines",
)
layout1 = Layout(
plot_bgcolor="#FFFFFF",
paper_bgcolor="#FFFFFF",
title="title",
height=550,
xaxis=dict(showgrid=True, showline=True, zeroline=False, fixedrange=True, title="% Campaign Completion", range=[0, 100]),
yaxis=dict(showline=True, fixedrange=True, zeroline=False, title="Audience Reached (%)", range=[0, (reach_increment + 10)]),
margin=plotly.graph_objs.layout.Margin(t=45, l=50, r=50),
)
linear = Scatter(
y=dff_match_data["Final"],
x=dff_match_data["percentage"],
name="title",
line=plotly.graph_objs.scatter.Line(color="black"),
mode="lines",
)
return Figure(data=[overlap, linear], layout=layout1)
@app.callback(Output("example-graph", "figure"),
[Input("submit_button", "n_clicks")],
[State("intermediate-value2", "children"),
State("Income", "value")])
def update_graph(n_clicks, employee_data_temp, inc):
if employee_data_temp is not None:
dff = pd.read_json(employee_data_temp, orient="split")
trace = Scatter(
y=dff["income_percent"], x=dff["inc"], line=plotly.graph_objs.scatter.Line(color="#1a2d46"), mode="lines"
)
layout1 = Layout(
plot_bgcolor="#FFFFFF",
paper_bgcolor="#FFFFFF",
height=450,
title="Digital - " + str(max_income) + " " + "%",
xaxis=dict(showgrid=True, showline=True, zeroline=True, fixedrange=True, title="Total Income"),
yaxis=dict(showline=True, fixedrange=True, zeroline=True, title="Income (%)"),
margin=plotly.graph_objs.layout.Margin(t=45, l=50, r=50),
)
return Figure(data=[trace], layout=layout1)