#python #plotly-dash
#python #plotly-dash
Вопрос:
Я работаю над приложением plotly dash. У меня есть почти рабочий пример. Единственное, что не работает, это то, что я не могу ограничить функции, определенные в обратных вызовах, не запускаться при загрузке страницы.
Я попытался добавить проверки для n_clicks внутри обратного вызова, однако, похоже, это не работает. Он также запускает функцию без щелчков
Ниже приведен код для dash
from datetime import date
import base64
import dash
import plotly
import dash
from dash.dependencies import Input, Output, State
from plotly.graph_objs import *
from datetime import datetime as dt
import dash_html_components as html
import dash_core_components as dcc
import flask
import pandas as pd
server = flask.Flask('app')
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash('app', server=server, external_stylesheets=external_stylesheets)
app.layout = html.Div(style={'backgroundColor': '#EFEAEA', 'margin': '0px', 'padding': '0px'}, children=[
html.Div([
html.Div([
html.Img(src='data:image/png;base64,{}'.format(encoded_image.decode()),
style={'width': '200px', 'height': '100px', 'display': 'inline-block', 'float': 'left', 'padding-left': '5px', 'padding-top': '5px'})
]),
html.Div([
html.Div([
html.Div([
dcc.Dropdown(
id='demographics',
options=[
{'label': 'All 18-49', 'value': '18_39'},
{'label': 'Female 25-54', 'value': '25_54 F'},
{'label': 'All 25-54', 'value': '25-54'},
],
placeholder="Select Demographics",
)
],
style={'width': '30.5%', 'display': 'inline-block', 'padding-right': '10px'}),
html.Div([
dcc.DatePickerRange(
id='my-date-picker-range',
start_date_placeholder_text="Select a Start Date",
end_date_placeholder_text="Select an End Date",
min_date_allowed=dt(2018, 1, 1),
max_date_allowed=dt(2050, 12, 31),
initial_visible_month=dt(2019, 1, 2),
style={'width': '600', 'display': 'inline-block', 'padding-right': '10px'}
),
html.Div(id='output-container-date-picker-range')
],
style={'width': '30.3%', 'display': 'inline-block', 'padding-right': '10px', 'position': 'relative'})
],
style={
'backgroundColor': '#EFEAEA',
'padding': '5px 10px'}),
html.Div([
html.Div([
dcc.Dropdown(
id='Horsepower',
options=[
{'label': '200', 'value': 'two_hundred'},
{'label': '250', 'value': 'two_hundred_fifty'},
{'label': '300', 'value': 'three_hundred'},
{'label': '350', 'value': 'three_hundred_fifty'},
{'label': '400', 'value': 'four_hundred'}
],
placeholder="Select TARP",
)
],
style={'width': '20%', 'display': 'inline-block', 'padding-right': '10px'}),
html.Div([
dcc.Dropdown(
id='Kilometers',
options=[
{'label': '250,000', 'value': 250000, 'type': 'number'},
{'label': '500,000', ''value': 500000, 'type': 'number'},
{'label': '750,000', 'value': 750000, 'type': 'number'},
{'label': '1,000,000', 'value': 1000000, 'type': 'number'},
],
placeholder="Select Impressions",
)
],
style={'width': '20%', 'display': 'inline-block', 'padding-right': '10px'}),
html.Div([
dcc.Dropdown(
id='Speed',
options=[
{'label': 'Low', 'value': 50, 'type': 'number'},
{'label': 'Average', 'value': 100, 'type': 'number'},
{'label': 'High', 'value': 150, 'type': 'number'},
],
placeholder="Select Frequency",
)
],
style={'width': '20%', 'display': 'inline-block', 'padding-right': '10px'}),
html.Div([
html.Button('Submit', id='submit_button', type='submit', n_clicks=1,
style={'width': '100px', 'height': '34.5px', 'margin-bottom': '8px',
'border-radius': '4px', 'display': 'inline-block', 'background-color': '#2D91C3', 'color': 'white'})
],
style={'display': 'inline-block', 'padding-bottom': '20px', 'verticalAlign': 'middle'}),
], style={
'backgroundColor': '#EFEAEA',
'padding': '5px'})
], style={'position': 'relative', 'left': '250px'})
]),
html.Div([
html.Div([
dcc.Graph(id='example-graph', config={'modeBarButtonsToRemove': ['pan2d', 'lasso2d', 'sendDataToCloud',
'select2d', 'autoScale2d', 'resetScale2d',
'toggleSpikelines',
'hoverClosestCartesian']})
],
style={'width': '49.3%', 'display': 'inline-block', 'border': 'thin grey solid', 'margin-left': '5px',
'margin-right': '2.5px', 'margin-top': '5px', 'margin-bottom': '2.5px'}),
html.Div([
dcc.Graph(id='example-graph1')
],
style={'width': '49.3%', 'display': 'inline-block', 'border': 'thin grey solid', 'margin-left': '2.5px',
'margin-right': '5px', 'margin-top': '5px', 'margin-bottom': '2.5px', 'backgroundColor': '#EFEAEA'})
], style={'backgroundColor': '#EFEAEA'}),
html.Div([
dcc.Graph(id='graph1')
],
style={'width': '99.2%', 'height': '120%', 'display': 'inline-block', 'border': 'thin grey solid', 'margin-left': '2.5px',
'margin-right': '5px', 'margin-top': '5px', 'margin-bottom': '2.5px', 'backgroundColor': '#EFEAEA'})
])
@app.callback(Output('example-graph1', 'figure'),
[Input('submit_button', 'n_clicks')],
[State('my-date-picker-range', 'start_date'),
State('my-date-picker-range', 'end_date')])
def update_graph(n_clicks, start_date, end_date):
if n_clicks > 0:
df = df_new
start_date_temp = dt.strptime(start_date, '%Y-%m-%d')
end_date_temp = dt.strptime(end_date, '%Y-%m-%d')
start_date_new = start_date_temp.replace(start_date_temp.year - 1)
end_date_new = end_date_temp.replace(end_date_temp.year - 1)
end_date_string = end_date_new.strftime('%Y-%m-%d')
start_date_string = start_date_new.strftime('%Y-%m-%d')
mask = (df['Date'] >= start_date_string) amp; (df['Date'] <= end_date_string)
filtered_df = df.loc[mask]
trace = Scatter(
y=filtered_df['Weights'],
x=filtered_df['Date'],
line=plotly.graph_objs.scatter.Line(
color='#42C4F7'
),
hoverinfo='skip',
error_y=plotly.graph_objs.scatter.ErrorY(
type='data',
array=filtered_df['Gender'],
thickness=1.5,
width=2,
color='#B4E8FC'
),
mode='lines'
)
layout1 = Layout(
height=450,
xaxis=dict(
showgrid=False,
showline=False,
zeroline=False,
fixedrange=True,
title='Time Elapsed (sec)'
),
yaxis=dict(
showline=False,
fixedrange=True,
zeroline=False,
),
margin=plotly.graph_objs.layout.Margin(
t=45,
l=50,
r=50
)
)
return Figure(data=[trace], layout=layout1)
else:
return {"I am the boss"}
Причина, по которой я предполагаю, что проверки n_clicks не работают, потому что я получаю следующую ошибку
TypeError: strptime() argument 1 must be str, not None
Я полагаю, что ошибка связана с приведенным ниже кодом внутри функции, поскольку при первой загрузке страницы start_date будет иметь тип none .
start_date_temp = dt.strptime(start_date, '%Y-%m-%d')
Может кто-нибудь, пожалуйста, помочь решить проблему. Я ожидаю, что при загрузке страницы функция обратного вызова не должна запускаться.
Заранее большое спасибо!!
Комментарии:
1. Просто для ясности, вы видите эту ошибку при загрузке страницы? Т.е. перед первым нажатием кнопки отправки?
2. @cosmic_inquiry, да, я вижу ошибку, как только загружаю страницу, прежде чем нажать на кнопку отправки. Когда я ввожу входные данные в окне выбора даты на интерфейсе и нажимаю кнопку отправки. Он работает просто отлично, и графики загружаются отлично. Это единственная ошибка, которую я получаю
Ответ №1:
Вот ваша проблема:
html.Button('Submit', id='submit_button', type='submit', n_clicks=1,
Вы предварительно n_clicks
настроили значение. Просто удалите эту n_clicks=1
часть, и она загрузит страницу как None
. Затем вам нужно будет проверить n_clicks
, как это (или подобное):
if n_clicks is not None and n_clicks > 0:
Это сработало для меня и работало до тех пор, пока не сломалось в моем примере df
.
Комментарии:
1. Если вы не возражаете, я задам еще один вопрос. Есть ли какая-либо библиотека, которую вы можете использовать, кроме dcc.graph. Я пытался использовать электронные диаграммы, но почему-то это не работает.
2. Извините, но я не знаком с другим, который я мог бы порекомендовать.
3. Есть еще одна вещь, если вы не возражаете, если я спрошу. Я пытался настроить свой datepickerrange. Однако я не смог этого сделать. Я искал везде в Интернете, однако я не нашел ни одной статьи, в которой рассказывалось бы о том, как настроить диапазон выбора даты. В любом случае, я могу настроить свой диапазон выбора даты. Я обновил макет своего приложения, если вы хотите взглянуть. Я не хотел публиковать еще один вопрос только для этого.
4. Это может стоить другого вопроса, потому что вам придется более подробно объяснить, как вы хотите его настроить. Я полагаю, вы уже проверили их, но вот документы на всякий случай.
5. Конечно, сделал бы это. Я просмотрел эту документацию, но ничего не говорит о ее настройке с точки зрения ширины и высоты