Python – Update table values in real time using Dash and Plotly

Update table values in real time using Dash and Plotly… here is a solution to the problem.

Update table values in real time using Dash and Plotly

I’m trying to build a dash app in Python to simulate the Q-Learning problem. Before implementing the algorithm, I just focused on making the table work increment randomly and wait 1 second between each increment.

Q Here is a pandas data frame:

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 was able to get it to work with the print statement and the values of the table on the console did get updated.

However, in the browser it is only updated for 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?

Solution

Resolved. There’s nothing better than drinking coffee in the morning; )

It is best to wrap the creation of the table into a function and call it at every interval for each update. Also, the previous syntax does not retain the styles defined in the first table that is 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

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 this helps!

Related Problems and Solutions