Black Lives Matter. Please consider donating to Black Girls Code today.
Dash HoloViews is now available! Check out the docs.

Update Dash Tables

Hi all,

I am trying to build a dash app in Python to simulate a Q-Learning problem. Before implementing the algorithm I am just focusing on making the table work incrementing randomly the values and waiting 1 sec between each increment.

Q is a pandas dataframe here:

table = ff.create_table(Q,  height_constant=20)
table.layout.width=300

def update_Q(Q):
    for i in range(len(Q)):
        for j in range(1, len(Q.columns)):        
            Q.iloc[i,j] += np.random.choice([0,1,2])
    print(Q)
    return Q

I am able to make it work with that print statement, the value of the table on the console is indeed getting updated.
However, in the browser it just get updated the first time, but then it remains static. Here is the code:

# Browser visualization

app.layout = html.Div([
        html.H1(children='Frozen Lake: Q-Learning Demo'),
        dcc.Graph(id='table', figure=table),
        dcc.Interval(
            id='time',
            interval=1*1000, # in milliseconds
            n_intervals=0)
        ]
    )

    
@app.callback(Output(component_id = 'table', component_property='figure'),
              [Input(component_id = 'time', component_property='n_intervals')])    
def update_table(n):   
    # Update values
    new_table = ff.create_table(update_Q(Q))
    time.sleep(1)
    return new_table
    

if __name__ == '__main__':
    app.run_server()

What am I missing?

Thanks!

SOLVED!.
Nothing like a morning caffee ; )

It is better to wrap the creation of the table into a function and call it for every update at every interval. Furthermore, previous syntax won’t keep style defined in the first table created.

# Helper functions to draw and update values of the table
def draw_Table(Q):
    table = ff.create_table(Q, index=True, height_constant=20)
    table.layout.width=300
    return table

def update_Q(Q):
    for i in range(len(Q)):
        for j in range(1, len(Q.columns)):        
            Q.iloc[i,j] += np.random.choice([0,1,2])
    return Q

And then,

@app.callback(Output(component_id = 'table', component_property='figure'),
              [Input(component_id = 'time', component_property='n_intervals')])    
def update_table(n):   
    # Update values
    new_table = draw_Table(update_Q(Q))
    time.sleep(1)
    return new_table

Hope it helps someone!