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

Live chart updates not showing

Hi,

Im trying to create a live chart which updates every three seconds. Initially on loading the page the chart is blank and despite showing a basic layout.

Then, the first graph loaded looks perfectly fine.

However, on the second load the layout adjusts, but no bars are shown.

I have tried some variations but nothing seemed to have worked. I am also not getting any error message. The console only prints:
127.0.0.1 - - [16/Aug/2018 13:02:38] “POST /_dash-update-cPreformatted textomponent HTTP/1.1” 200 -

This the entire code:

import pandas as pd
import datetime
import dashboard_module as dm
import collections

import dash
from dash.dependencies import Input,Output, Event
import dash_core_components as dcc
import dash_html_components as html
import plotly
import plotly.graph_objs as go


# df = dm.return_all_pd_data(token = API_TOKEN)
df = pd.read_pickle("/Users/dpaul/Desktop/pickle")
i = collections.deque([1,2,3,4,5,6])

app = dash.Dash()

app.layout = html.Div(
    [
        
        dcc.Graph(id='live-graph', animate=True),
        dcc.Interval(
            id='graph-update',
            interval=3000
        ),
    ]
)

@app.callback(Output('live-graph', 'figure'),
              events=[Event('graph-update', 'interval')])
def update_graph():

    i.rotate()
    month = i[0]

    start = datetime.datetime(2018, month, 1, 0, 0, 0, 1)
    end = datetime.datetime(2018,  month+1, 1, 0, 0, 0, 1)
    subset_df = df[ (df["lost_time"] > start) & (df["lost_time"] < end) ]
    
    x = pd.value_counts(subset_df.deal_source).index
    y = pd.value_counts(subset_df.deal_source).values

    data = plotly.graph_objs.Bar(
            x=x,
            y=y,
            name='Barchart'
            )

    return {'data': [data],'layout' : go.Layout(xaxis=dict(range=[min(x),max(x)]),
                                                yaxis=dict(range=[min(y),max(y)]))}


if __name__ == "__main__":

    app.run_server(debug = True)

I have some table and bar plot updating every 5 seconds in my app as well. I see we have a few differences in how we structure this.
Here is a very simplified (may not be able to run) snippet of my code for comparison

app.layout = html.Div(
	children=[
		dcc.Tabs(
			tabs=[
				{'label': 'Hal 3', 'value': 1},
				{'label': 'Hal 4', 'value': 2},
				{'label': 'Tilgængelighed', 'value': 3},
				{'label': 'Præstation', 'value': 4},
				{'label': 'KPI', 'value': 5}

			],
			value=1,
			id='tabs'
		),
		html.Div(id='tab-output'),
		dcc.Interval(
			id='interval_component',
			interval=5*1000 # in miliseconds
		)
	]
)

@app.callback(
	Output('table_hal3', 'children'),
	[Input('interval_component', 'n_intervals')])
def update_table(n):
	return generate_table_left.generate_table(n)

So two things, both in the callback.

  1. You use something called events as input, I have not seen this before but if you have used it successfully before, this may not be the issue.
  2. My input gets n_intervals from my dcc.Interval component, you are using intervals as input. This may be where the fox is burried. (Not sure how well that saying is translated to english.:sweat_smile::thinking:)
1 Like

Thanks Blaceus. With some of your ideas and some other ones I was able to find the solution.

Indeed it is better to work with the n_intervals parameter, even though that was not the root issue.

Im posting my solution here in case somebody else might need it. This is the code I ended up with:

months = ["January", 
        "February", 
        "March", 
        "April", 
        "May", 
        "June", 
        "July", 
        "August", 
        "September", 
        "Oktober", 
        "November", 
        "December"]

# df = dm.return_all_pd_data(token = API_TOKEN)
df = pd.read_pickle("/Users/dpaul/Desktop/pickle")

app = dash.Dash()

app.layout = html.Div(
    [
        dcc.Graph(id='live-graph'),
        dcc.Interval(
            id='interval_component',
            interval=5000)
    ]
)

@app.callback(
    Output(component_id='live-graph', component_property='figure'),
    [Input(component_id='interval_component', component_property='n_intervals')])
def update_value(value):

    month = rd.randrange(1,5,1)
    start = datetime.datetime(2018, month, 1, 0, 0, 0, 1)
    end = datetime.datetime(2018,  month+1, 1, 0, 0, 0, 1)
    subset_df = df[(df["lost_time"] > start) & (df["lost_time"] < end)]

    x = pd.value_counts(subset_df.deal_source).index
    y = pd.value_counts(subset_df.deal_source).values

    fig = ({'data': [{'x': x, 'y': y, 'type': 'bar', 'name': value}],
            'title': "Showing month: {}".format(months[month-1]),
            'layout': go.Layout(xaxis=dict(range=[min(x),max(x)]), 
                                yaxis=dict(range=[min(y),max(y)*1.3]),
                                title = "Showing month: {}".format(months[month-1]))
            
        })
    return fig
1 Like