Search code examples
pythonjupyter-notebookplotly-dashdropdownbox

Error with Multi Dropdown List in Python Dash


I'm trying to visualize the price development of different financial indices (A, B, C) in an interactive line chart embedded in Python Dash. I want to allow users to select multiple indices and compare them accordingly in the same plot over a specific period of time. At the same time, the plot should also change accordingly when unselecting indices. So far, I was able to plot only one index. The issue I'm having now is that the the plot does not change at all when adding additional indices. I've tried to solve this issue myself for the last couple of hours, but without success, unfortunately.

I'm using Jupyter Notebook. Here's my code with a data sample:

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

data = [['2020-01-31', 100, 100, 100], ['2020-02-28', 101, 107, 99], ['2020-03-31', 104, 109, 193], ['2020-04-30', 112, 115, 94], ['2020-05-31', 112, 120, 189]]
df = pd.DataFrame(data, columns = ['DATE', 'A', 'B', 'C'])
df = df.set_index('DATE')
df

# create the Dash app
app = dash.Dash()

# set up app layout
app.layout = html.Div(children=[
    html.H1(children='Index Dashboard'),
    dcc.Dropdown(id='index-dropdown',
                options=[{'label': x, 'value': x}
                        for x in df.columns],
                 value='A',
                 multi=True, clearable=True),
    dcc.Graph(id='price-graph')
])

# set up the callback function
@app.callback(
    Output(component_id='price-graph', component_property='figure'),
    [Input(component_id='index-dropdown', component_property='value')]
)

def display_time_series(selected_index):
    filtered_index = [df.columns == selected_index]
    fig = px.line(df, x=df.index, y=selected_index,
                 labels={'x', 'x axis label'})
    
    fig.update_layout(
        title="Price Index Development",
        xaxis_title="Month",
        yaxis_title="Price",
        font=dict(size=13))
    
    return fig

# Run local server
if __name__ == '__main__':
    app.run_server(debug=True, use_reloader=False)

As I'm relatively new to Python Dash, any help or advice would be extremely appreciated!


Solution

  • You're not applying your filter inside your callback to your data and the filter itself doesn't work.

    Instead you can do something like this:

    @app.callback(
        Output(component_id="price-graph", component_property="figure"),
        [Input(component_id="index-dropdown", component_property="value")],
    )
    def display_time_series(selected_index):
        dff = df[selected_index] # Only use columns selected in dropdown
        fig = px.line(dff, x=df.index, y=selected_index, labels={"x", "x axis label"})
    
        fig.update_layout(
            title="Price Index Development",
            xaxis_title="Month",
            yaxis_title="Price",
            font=dict(size=13),
        )
    
        return fig