Black Lives Matter. Please consider donating to Black Girls Code today.

DataTable not updating with DatePickerSingle Callback

I am pretty new to dash and I have tried to read as much as I can to understand what the issue might be. In a nutshell I have a single datepicker which is an input to the DataTable and Graph callback. The graph callback is working fine so it is just the DataTable which is causing problems. I also tried the single input to multiple output callback but didnt work. My code is as below:

“”"
app = JupyterDash()

folder = os.getcwd()
portfolio_returns_table = pd.read_csv(Path(folder, 'portfolioreturns_maria.csv',parse_dates=[0]))
portfolio_returns_table = portfolio_returns_table.set_index('Unnamed: 0')
name_portfolioID_table = pd.read_csv(Path(folder, 'name_portfolioID.csv'))

#Calculate portfolio cumulative returns
df_cumret = (portfolio_returns_table+1).cumprod().round(5)

df_cumret.index = pd.to_datetime(df_cumret.index)

app.layout = html.Div(html.Div([dcc.DatePickerSingle(
    id='my-date-picker-single',
    min_date_allowed=dt.date(df_cumret.index.min()),
    max_date_allowed=dt.date(df_cumret.index.max()),
    initial_visible_month=dt.date(df_cumret.index.max()),
    date = dt.date(df_cumret.index.max())
,display_format = 'Y-MM-DD',clearable = True), 
html.Div(id='output-container-date-picker-single'),
html.Div(dash_table.DataTable(id = 'data_table',
data = [],
fixed_rows={'headers': True},
style_cell = {'textAlign': 'left'},
style_table={'height': 400})), 
dcc.Graph('my_graph'), 
html.Div(id='intermediate-value', style={'display': 'none'})
                        
]))

@app.callback([Output('data_table','data'),Output('data_table','columns')],[Input('my-date-picker-single','date')])    
def update_leader_table(date):


 #Get data for the selected date and transpose
 df_T = df_cumret.loc[[dt.date(date)]].T

 #Sort the table to reveal the top leaders
 df_Top = df_T.sort_values(df_T.columns[0], ascending=False)[:10]

 #Convert the index to an interger
 df_Top.index = df_Top.index.astype(int)

 #Generate the leaderboard to given date
 df_leader = pd.merge(df_Top,name_portfolioID_table, left_index=True,right_index=True, how = 'left')

 #Create the col rank
 df_leader['Rank'] = range(1,len(df_leader)+1)

 df_leader.columns = ['Cum Return', 'Investor','Rank']

 df_leader.reset_index(drop = True, inplace = True)


 data = df_leader.to_dict('records')
 columns= [{'id': c, 'name': c,"deletable": True, "selectable": True} for c in df_leader.columns]

 return (data, columns)

#callback to link calendar to graph
 @app.callback(Output('my_graph','figure'),[Input('my-date-picker-single','date')])
 def update_graph(date):
   #date filter
   df_T = df_cumret.loc[:date].T

  #Sort the table to reveal the top leaders & filter for leaderboard
  df_Top = df_T.sort_values(df_T.columns[-1], ascending=False)[:10]

  #Transpose to have date as index
  df_top_graph = df_Top.T

  #set the columns as an Int
  df_top_graph.columns = df_top_graph.columns.astype(int)

  #Rename columns
  df_top_graph.rename(columns=dict(zip(name_portfolioID_table.index, name_portfolioID_table.name)), inplace=True)

#Generate graph
fig = px.line(df_top_graph, x = df_top_graph.index, y = df_top_graph.columns, title='ETF LEADERBOARD PERFORMANCE: '+date, labels={'Unnamed: 0':'Date','value':'Cumulative Returns'})

fig.update_layout(hovermode = 'x unified')
fig.update_traces(hovertemplate='Return: %{y} <br>Date: %{x}')
fig.update_layout(legend_title_text = 'Investor')

return fig

if __name__ == '__main__':
  app.run_server(mode = 'inline',debug=True)

“”"
Greatly appreciate any assistance you can provide

Hi @nickmuchi,

I don’t see anything obvious. Can you describe what the issue is – Are you getting a error messages? Is the table just blank? Can you share some sample data so the problem is reproducible?

Hi @AnnMarieW, thanks for your time, I am getting the below error, seems the date string from datepicker is unable to filter the df:

KeyError Traceback (most recent call last)
in update_leader_table(date=‘2020-10-12’)
33
34 #Get data for the selected date and transpose
—> 35 df_T = df_cumret.loc[[date]].T
df_T = undefined
global df_cumret.loc = <pandas.core.indexing._LocIndexer object at 0x00000228C80119F8>
date.T = undefined
36
37 #Sort the table to reveal the top leaders

~\anaconda3\lib\site-packages\pandas\core\indexing.py in getitem(
self=<pandas.core.indexing._LocIndexer object>,
key=[‘2020-10-12’]
)
1765
1766 maybe_callable = com.apply_if_callable(key, self.obj)
-> 1767 return self._getitem_axis(maybe_callable, axis=axis)
self._getitem_axis = <bound method _LocIndexer._getitem_axis of <pandas.core.indexing._LocIndexer object at 0x00000228C7F4EEF8>>
maybe_callable = [‘2020-10-12’]
axis = 0
1768
1769 def _is_scalar_access(self, key: Tuple):

~\anaconda3\lib\site-packages\pandas\core\indexing.py in _getitem_axis(
self=<pandas.core.indexing._LocIndexer object>,
key=[‘2020-10-12’],
axis=0
)
1951 raise ValueError(“Cannot index with multidimensional key”)
1952
-> 1953 return self._getitem_iterable(key, axis=axis)
self._getitem_iterable = <bound method _NDFrameIndexer._getitem_iterable of <pandas.core.indexing._LocIndexer object at 0x00000228C7F4EEF8>>
key = [‘2020-10-12’]
axis = 0
1954
1955 # nested tuple slicing

~\anaconda3\lib\site-packages\pandas\core\indexing.py in _getitem_iterable(
self=<pandas.core.indexing._LocIndexer object>,
key=[‘2020-10-12’],
axis=0
)
1592 else:
1593 # A collection of keys
-> 1594 keyarr, indexer = self._get_listlike_indexer(key, axis, raise_missing=False)
keyarr = undefined
indexer = undefined
self._get_listlike_indexer = <bound method _NDFrameIndexer._get_listlike_indexer of <pandas.core.indexing._LocIndexer object at 0x00000228C7F4EEF8>>
key = [‘2020-10-12’]
axis = 0
global raise_missing = undefined
1595 return self.obj._reindex_with_indexers(
1596 {axis: [keyarr, indexer]}, copy=True, allow_dups=True

~\anaconda3\lib\site-packages\pandas\core\indexing.py in _get_listlike_indexer(
self=<pandas.core.indexing._LocIndexer object>,
key=[‘2020-10-12’],
axis=0,
raise_missing=False
)
1550
1551 self._validate_read_indexer(
-> 1552 keyarr, indexer, o._get_axis_number(axis), raise_missing=raise_missing
keyarr = Index([‘2020-10-12’], dtype=‘object’, name=‘Unnamed: 0’)
indexer = array([-1], dtype=int64)
o._get_axis_number = <bound method NDFrame._get_axis_number of <class ‘pandas.core.frame.DataFrame’>>
axis = 0
raise_missing = False
1553 )
1554 return keyarr, indexer

~\anaconda3\lib\site-packages\pandas\core\indexing.py in _validate_read_indexer(
self=<pandas.core.indexing._LocIndexer object>,
key=Index([‘2020-10-12’], dtype=‘object’, name=‘Unnamed: 0’),
indexer=array([-1], dtype=int64),
axis=0,
raise_missing=False
)
1637 if missing == len(indexer):
1638 axis_name = self.obj._get_axis_name(axis)
-> 1639 raise KeyError(f"None of [{key}] are in the [{axis_name}]")
global KeyError = undefined
1640
1641 # We (temporarily) allow for some missing keys with .loc, except in

KeyError: “None of [Index([‘2020-10-12’], dtype=‘object’, name=‘Unnamed: 0’)] are in the [index]”

When I test run the df_T outside of the callback i get the below:

global df: df_cumret

|Unnamed: 0| |0 | 1 |2 | 3 | 4 | 5
|2020-01-02| 1.00000| 1.00000| 1.00000| 1.00000| 1.00000| 1.00000
|2020-01-03| 0.99984| 1.00227| 1.00210| 1.00430| 1.00658| 1.00403
|2020-01-06| 1.00083| 1.00475| 1.00239| 1.01061| 1.01676| 1.01058
|2020-01-07| 1.00713| 1.02080| 1.00792| 1.02016| 1.03356| 1.02116
|2020-01-08| 1.01037| 1.03293| 1.00985| 1.02990| 1.04990| 1.03415

desired result when filtered by date (which i am trying to select using datepicker) and transposed: df_cumret.loc[[date]].T

Unnamed: 0 2020-03-30
0 0.07545
1 0.08436
2 0.09632
3 0.24193
4 0.45133
5 0.43527
6 0.08286
7 0.05080
8 1.42347
9 0.17099
10 2.38203

looked like it worked after converting the date from datepicker to datetime, had assumed it would be in dt already as I had declared in the the layout with date = dt.date(df_cumret.index.max()).

Thanks for taking a look, much appreciated

1 Like