Graph not updating upon selecting new dropdown value

Hey guys!

I’m an intern python developer and I just found out about dash and Plotly, its amazing!
For my app I’m using a dataset containing info about fortune 500’s revenue in 1955-2005 period.

The problem I have is that the graph won’t update itself upon selecting additional company from the dropdown list, however, if I select a new company and delete a previous one - then the graph updates. It seems like something prevents the graph to show multiple lines at once. Also, is there any way I could add the legend telling which color is what company? Below is my code:

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

#Read CSV and change col. names
df = pd.read_csv('fortune500-full.csv')
df.columns = ['Year', 'Rank', 'Company', 'Revenue', 'Profit']

#Get a list of unique company names
Companies = df['Company'].unique()

#Stylesheet
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

#App layout
app.layout = html.Div([
#Dropdown
html.Div([
html.Label('Dropdown'),
    dcc.Dropdown(
        id = 'Dropdown',
        options=[{'label': i, 'value': i} for i in Companies],
        value=["General Motors"],
        multi = True
    ),]),

#Graph
    dcc.Graph(
        id='Graph',
        figure={
            'data': [
                go.Scatter(
                    x=df.loc[df['Company'] == i, 'Year'],
                    y=df.loc[df['Company'] == i, 'Revenue'],
                    text =df.loc[df['Company'] == i, 'Company'],
                    mode='lines',
                    name=i
                ) for i in df.Company.unique()],

            'layout': go.Layout(
                xaxis={'title': 'Year'},
                yaxis={'title': 'Revenue'},
                margin={'l': 50, 'b': 30, 't': 10, 'r': 0},
                legend={'x': 1, 'y': 1},
                hovermode='closest'
            )}),

    html.Div(dcc.RangeSlider(
        id='Slider',
        min=df['Year'].min(),
        max=df['Year'].max(),
        value=[1955, 2005],
        marks={str(year): str(year) for year in df['Year'].unique()}
    ), style={'width': '98%', 'padding': '0px 20px 20px 20px'}),

    html.Div(id='Output_slider',
             style={'textAlign': 'center', 'color': ['#7FDBFF']}
             )])

@app.callback(
    dash.dependencies.Output('Graph', 'figure'),
    [dash.dependencies.Input('Dropdown', 'value')])

def callback_a(dropdown_value):
    trace = []
    for val in dropdown_value:
        trace.append(
            go.Scatter(
                x=df.loc[df['Company'] == val, 'Year'],
                y=df.loc[df['Company'] == val, 'Revenue'],
                text =df.loc[df['Company'] == val, 'Company'],
                mode='lines',
                name=val
            ),)
        layout = go.Layout(
            xaxis={'title': 'Year'},
            yaxis={'title': 'Revenue'},
            margin={'l': 50, 'b': 30, 't': 10, 'r': 0},
            legend={'x': 1, 'y': 1},
            hovermode='closest'
        )
        figure = {'data': trace, 'layout': layout}
        return figure


@app.callback(
    dash.dependencies.Output('Output_slider', 'children'),
    [dash.dependencies.Input('Slider', 'value')])
def update_output(value):
    return 'Wybrane lata:  "{}"'.format(value)
#App
if __name__ == '__main__':
    app.run_server(debug=True)

Could any of you please take a look at this and help me find root of this problem?

Kind regards.

To me, it looks like your declaration of figure and return figure is inside your for-loop for appending traces, you need to indent it outside the loop in my opinion.

def callback_a(dropdown_value):
    trace = []
    for val in dropdown_value:
        trace.append(
            go.Scatter(
                x=df.loc[df['Company'] == val, 'Year'],
                y=df.loc[df['Company'] == val, 'Revenue'],
                text =df.loc[df['Company'] == val, 'Company'],
                mode='lines',
                name=val
            ),)
        layout = go.Layout(
            xaxis={'title': 'Year'},
            yaxis={'title': 'Revenue'},
            margin={'l': 50, 'b': 30, 't': 10, 'r': 0},
            legend={'x': 1, 'y': 1},
            hovermode='closest'
        )
        figure = {'data': trace, 'layout': layout}
        return figure

Dear Blaceus,

Thank you a lot! That solved the case for me :).
I’m very grateful, thank you! It also added the legend on itself, which I wanted to do manually :).

Kind Regards.

1 Like