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

Dropdowns to create interactive graphs not working

I’ve been trying to get this dropdown working for weeks with no success, What am I doing wrong?

import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import plotly.graph_objects as go
import Macro

app = dash.Dash(name,)

app.layout = html.Div([

html.Label('Dropdown'),
dcc.Dropdown(
    id='Dropdown_1',
    options=[
        {'label': 'US Index', 'value': Macro.US_Macro},
        {'label': 'EU Index', 'value': Macro.EU_Macro},
    ],
    value = Macro.US_Macro,
    multi = True
),


html.H1(
    children='Global Economies',
    style={
        'textAlign': 'center',
        'color': '#7FDBFF'
    }
),


dcc.Graph(id='Graph1'),

])

@app.callback(
Output(component_id=‘Graph1’, component_property=‘figure’),
[Input(component_id=‘Dropdown_1’, component_property= ‘value’)]
)
def update_graph(input_value):

return {
    'data': [
        go.Scatter(
            x = input_value['x'],
            y = input_value['y'],
            mode='lines',
            name= input_value['name'],
            marker = input_value['marker']
        )
    ],
    'layout': go.Layout(
        dragmode='pan', 
    )
}     

if name == ‘main’:
app.run_server(debug=True)

Code from Macro.py which the above code is referencing:

US_Macro = {‘x’: US.index, ‘y’: US, ‘name’: ‘United States’, ‘marker’: {‘color’: ‘lime’}}
EU_Macro = {‘x’: EU.index, ‘y’: EU, ‘name’: ‘European Union’, ‘marker’: {‘color’: ‘blue’}}

where US and EU are pandas dataframes.

always I get invalid value passed to dropdown error, and the dropdown doesn’t even load.

The value can only be a string or a number, not an arbitrary object. Typical approaches for your use case are,

  1. Serialize your object to a string, and deserialize it in the callback.
  2. Store the objects somewhere (in memory, in a file, etc.) where they can be looked up via a key. Use the key as value in the drop down and lookup the object in the callback.

Thank you, that definitely got me further. I added a dictionary of values and keys called all_options , and referenced the string values in the dropdown and pass those into the callback.
My function in the callback now looks like:

def update_graph(input_value):

return {
    'data': [
        go.Scatter(
            x = all_options[input_value]['x'],
            y = all_options[input_value]['y'],
            mode='lines',
            name= all_options[input_value]['name'],
            marker = all_options[input_value]['marker']
        )
    ],
    'layout': go.Layout(
        dragmode='pan', 
    )
}    

When I start the app, I get the dropdown to show up as well as the first plot with no errors, though when I try to edit the graph in any way from the dropdown, then I get:

TypeError: unhashable type: ‘list’

Traceback (most recent call last)
File “/home/jsgart/VSCode/Macro Indicator/app.py”, line 58, in update_graph
x = all_options[input_value][‘x’],
TypeError: unhashable type: ‘list’
Traceback (most recent call last):
File “/home/jsgart/VSCode/Macro Indicator/app.py”, line 58, in update_graph
x = all_options[input_value][‘x’],
TypeError: unhashable type: ‘list’

Upon inspection it looks like even though I have one initial value set, that all the values of the dropdown are trying to get passed in at once? I am guessing this is normal behavior and that I now need to process these values in a for loop?

Got it! Modified the function in the callback to:

def update_graph(input_value):
traces =
selected_plot = input_value

for input_value in selected_plot:
    traces.append(dict(
        x = all_options[input_value]['x'],
        y = all_options[input_value]['y'],
        mode='lines',
        name= all_options[input_value]['name'],
        marker = all_options[input_value]['marker']
    ))

return {
    'data': traces,
    'layout': go.Layout(
        dragmode='pan', 
    )
}    

Thank you Emil, for responding so fast after my initial post and pointing me in the right direction! I’ve been wrestling with this first Dash app of mine for weeks!

1 Like