Updating DataTable with DatePickerRange

The initial DataTable is visible, but does not update when the DatePickerRange component is changed.

The layout consists of two dcc components; a DatePickerRange and a DataTable. The DataTable displays a dataframe with Date as one of the columns.

data = pd.read_csv("original_data.csv")
data['Date'] = pd.to_datetime(data['Date'], errors='coerce')

# *transformation steps on 'data' to produce 'df'*
col_a_sum = data['col_a'].sum()
col_b_sum = data['col_b'].sum()
col_c_sum = data['col_c'].sum()

df = pd.DataFrame([col_a_sum, col_a_sum, col_a_sum]).T 

app.layout = html.Div([
dcc.DatePickerRange(
    id = 'my_date_picker',
    min_date_allowed = df['Date'].min(),
    max_date_allowed = df['Date'].max(),
    initial_visible_month = df['Date'].min(),
    end_date = df['Date'].max()
    ),
    
dt.DataTable(
    id='comparison-table',
    columns=[{"name": i, "id": i} for i in df.columns],
    data=df.to_dict("rows"),
    editable=False,
    filtering=False,
    sorting=True,
    sorting_type="multi",
    row_selectable="multi",
    row_deletable=False,
    selected_rows=[],
)
])

The callback is as follows:

@app.callback(
Output('comparison-table', 'data'), # used to be 'data'
[Input('my_date_picker', 'initial_visible_month'),
Input('my_date_picker', 'end_date')])

def update_table(start_date, end_date):
    # filter based on inputs from DatePickerRange
    data_filtered = data.loc[(data['Date'] >= start_date) & (data['Date'] <= end_date)]

    # *transformation steps on 'data' to produce 'df'*
    col_a_sum = data_filtered['col_a'].sum()
    col_b_sum = data_filtered['col_b'].sum()
    col_c_sum = data_filtered['col_c'].sum()

    df = pd.DataFrame([col_a_sum, col_a_sum, col_a_sum]).T 
    return df

if __name__ == '__main__':
    app.run_server() # if running locally

Any help would be appeciated. I am new to dash so perhaps I am missing something obvious.

Hi there

I think the inputs for your callback should be start_date and end_date rather than initial_visible_month and end_date?

See first callback example here:

https://dash.plot.ly/dash-core-components/datepickerrange

Hi,

Thanks for your suggestion. I made that change, but unfortunately the DataTable still doesn’t update according to the DatePickerRange inputs.

It’s probably worth mentioning that I have a figure that works correctly based on those callback inputs:

app.callback(
Output('graph', 'figure'),
[Input('my_date_picker', 'initial_visible_month'),
Input('my_date_picker', 'end_date')])

def update_graph(start_date, end_date):

    data = data.loc[(data['Date'] >= start_date) & (data['Date'] <= end_date)]

    # *transformation steps on 'data' to produce 'df'*
    col_a_sum = data['col_a'].sum()
    col_b_sum = data['col_b'].sum()
    col_c_sum = data['col_c'].sum()

    stats = pd.Series([col_a_sum, col_b_sum, col_c_sum], 
                           index = ['col_a', 'col_b', 'col_c']).astype('int')

    trace = go.Bar(
                x=stats.index, 
                y=stats,
                name = stats.index
            )

    return {
        'data': [trace]}

Try changing the last line of your callback from:

return df

to:

return df.to_dict("rows")

?

I followed the example here, albeit without pagination and now the DataTable is updating.

It seems that the key changes that allowed the table to update were:

  1. to leave the data argument empty. i.e.
dt.DataTable(
    id='comparison-table',
    columns=[{"name": i, "id": i} for i in df.columns]
)

instead of:

dt.DataTable(
    id='comparison-table',
    columns=[{"name": i, "id": i} for i in df.columns],
    data=df.to_dict("rows")
)
  1. return df.to_dict(‘rows’) as you correctly suggested

def update_table(start_date, end_date):
#filter based on inputs from DatePickerRange
data_filtered = data.loc[(data[‘Date’] >= start_date) & (data[‘Date’] <= end_date)]

col_a_sum = data_filtered['col_a'].sum()
col_b_sum = data_filtered['col_b'].sum()
col_c_sum = data_filtered['col_c'].sum()
df = pd.DataFrame([col_a_sum, col_a_sum, col_a_sum]).T 
return df.to_dict('rows')   
  1. reference ‘initial_visible_month’ instead of ‘start_date’ in the callback.

@app.callback(
Output(‘comparison-table’, ‘data’), # used to be ‘data’
[Input(‘my_date_picker’, ‘initial_visible_month’),
Input(‘my_date_picker’, ‘end_date’)])date_picker’, ‘end_date’)])

Apologies for the formatting; I couldn’t get it to work for the life of me.

Thanks for the help!

1 Like

Hi @tjb ,
I have a similar problem but I still cannot figure out how to fix it, can you check my post?

thanks!!