В тире, как использовать обратный вызов для обновления графика, когда выбран переключатель?
Я новичок в тире, и у меня возникают проблемы с поиском примеров использования фреймов данных в обратном вызове. Я создал еженедельную радио-кнопку и ежемесячную радио-кнопку.
Когда выбран ежемесячный переключатель, я бы хотел, чтобы график извлекал данные из df_monthly
где каждый бар будет ежемесячной суммой оплаты. Когда установлен переключатель еженедельно, я бы хотел, чтобы график заполнял каждую полосу еженедельно, то есть каждую строку в кадре данных, поскольку мне платят раз в неделю.
Я не уверен, где я иду не так, но я получаю сообщение об ошибке TypeError: update_fig() takes 0 positional arguments but 1 was given
График заполняется без данных, как на картинке ниже. Спасибо за любую помощь в этом вопросе.
import dash
import dash_core_components as dcc
import dash_html_components as html
import plotly.plotly as py
import plotly.graph_objs as go
import sqlite3
import pandas as pd
from functools import reduce
import datetime
conn = sqlite3.connect('paychecks.db')
df_ct = pd.read_sql('SELECT * FROM CheckTotal',conn)
df_earn = pd.read_sql('SELECT * FROM Earnings', conn)
df_whold = pd.read_sql('SELECT * FROM Withholdings', conn)
data_frames = [df_ct, df_earn, df_whold]
df_paystub = reduce(lambda left,right: pd.merge(left,right,on=['Date'], how='outer'), data_frames)
def date_extraction(df):
df['Date'] = pd.to_datetime(df['Date'])
df['Year'] = df['Date'].dt.strftime('%Y')
df['Month'] = df['Date'].dt.strftime('%B')
df['Day'] = df['Date'].dt.strftime('%d')
return df
date_extraction(df_paystub)
df_monthly = df_paystub.groupby(['Month']).sum()
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
app.css.append_css({'external_url': 'https://codepen.io/amyoshino/pen/jzXypZ.css'})
app.layout = html.Div(children=[
html.Div([
html.Div([
dcc.RadioItems(
id='data-view',
options=[
{'label': 'Weekly', 'value': 'Weekly'},
{'label': 'Monthly', 'value': 'Monthly'},
],
value='',
labelStyle={'display': 'inline-block'}
),
], className = 'two columns'),
html.Div([
dcc.Dropdown(
id='year-dropdown',
options=[
{'label': i, 'value': i} for i in df_paystub['Year'].unique()
],
placeholder="Select a year",
),
], className='five columns'),
html.Div([
dcc.Dropdown(
id='month-dropdown',
options=[
{'label': i, 'value': i} for i in df_paystub['Month'].unique()
],
placeholder="Select a month(s)",
multi=True,
),
], className='five columns'),
], className = 'row'),
# HTML ROW CREATED IN DASH
html.Div([
# HTML COLUMN CREATED IN DASH
html.Div([
# PLOTLY BAR GRAPH
dcc.Graph(
id='pay',
)
], className = 'six columns'),
# HTML COLUMN CREATED IN DASH
html.Div([
# PLOTLY LINE GRAPH
dcc.Graph(
id='hours',
figure={
'data': [
go.Scatter(
x = df_earn['Date'],
y = df_earn['RegHours'],
mode = 'lines',
name = 'Regular Hours',
),
go.Scatter(
x = df_earn['Date'],
y = df_earn['OtHours'],
mode = 'lines',
name = 'Overtime Hours',
)
]
}
)
], className='six columns')
], className='row')
], className='ten columns offset-by-one')
@app.callback(dash.dependencies.Output('pay', 'figure'),
[dash.dependencies.Input('data-view', 'value')])
def update_fig():
figure={
'data': [
go.Bar(
x = df_monthly['Month'],
y = df_monthly['CheckTotal'],
name = 'Take Home Pay',
),
go.Bar(
x = df_monthly['Month'],
y = df_monthly['EarnTotal'],
name = 'Earnings',
)
],
'layout': go.Layout(
title = 'Take Home Pay vs. Earnings',
barmode = 'group',
yaxis = dict(title = 'Pay (U.S. Dollars)'),
xaxis = dict(title = 'Date Paid')
)
}
return figure
if __name__ == "__main__":
app.run_server(debug=True)
1 ответ
Привет @prime90 и добро пожаловать в Dash.
Взглянув на вашу подпись обратного вызова, он выглядит как update_fig()
функция должна принять Input
Вы дали это (используя dash.dependencies.Input
).
Обратный звонок отправляет это Input
какие изменения в вашем приложении вы указали. Так что отправка по value
из #data-view
ты дал свою функцию update_fig()
, который в настоящее время не принимает никаких переменных, вызывающих сообщение об ошибке.
Просто обновите сигнатуру своей функции и добавьте пару логических переменных, чтобы избавиться от ошибки и получить потенциальную функциональность:
def update_fig(dataview_value):
# define your weekly OR monthly dataframe
# you'll need to supply df_weekly similarly to df_monthly
# though DO NOT modify these, see note below!
df = df_weekly if dataview == 'weekly' else df_monthly
dfkey = 'Week' if 'week' in df.columns else 'Month' # eh, worth a shot!
figure={
'data': [
go.Bar(
x = df[dfkey],
y = df['CheckTotal'],
name = 'Take Home Pay',
),
go.Bar(
x = df[dfkey],
y = df['EarnTotal'],
name = 'Earnings',
)
],
'layout': go.Layout(
title = 'Take Home Pay vs. Earnings',
barmode = 'group',
yaxis = dict(title = 'Pay (U.S. Dollars)'),
xaxis = dict(title = 'Date Paid')
)
}
return figure
Как было написано в комментариях выше, вам нужно будет выполнить некоторые предварительные манипуляции для создания df_weekly, как вы это сделали с вашим текущим df_monthly.
Кроме того, фрагмент кода, который я написал, предполагает, что столбец df называется "Неделя" и "Месяц"- очевидно, обновляйте их по мере необходимости.
Обработка данных в Dash:
Убедитесь, что вы читаете документы по совместному использованию данных, так как они подчеркивают, что данные никогда не должны изменяться вне области.
Надеюсь, это поможет:-)