В тире, как я могу использовать обратный вызов для обновления графика, когда выбран переключатель? - PullRequest
1 голос
/ 01 апреля 2019

Я новичок в dash, и у меня возникают проблемы с поиском примеров использования фреймов данных в обратном вызове. Я создал еженедельную радио-кнопку и ежемесячную радио-кнопку.

Когда выбрана месячная радиокнопка, я бы хотел, чтобы график извлекал данные из df_monthly, где каждый столбец был бы ежемесячной суммой оплаты. Когда установлен переключатель еженедельно, я бы хотел, чтобы график заполнял каждую полосу еженедельно, то есть каждую строку во фрейме данных, поскольку мне платят раз в неделю.

Я не уверен, где я иду не так, но я получаю сообщение об ошибке TypeError: update_fig() takes 0 positional arguments but 1 was given

График заполняется без данных, как на картинке ниже. Спасибо за любую помощь в этом вопросе.

enter image description here

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 Ответ

0 голосов
/ 03 апреля 2019

Привет @ 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:

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

Надеюсь, это поможет: -)

...