✊🏿 Black Lives Matter. Please consider donating to Black Girls Code today.
⚡️ Concerned about the grid? Kyle Baranko teaches how to predicting peak loads using XGBoost. Register for the August webinar!

Filter a line chart with dropdowns

Hi everyone,

I am trying to filter a line chart using a dropdown. The problem is that the dropdown which should filter the graph was populated using a callback.

I already have the code for the two dropdowns and for the graph. Now I would need a callback that filters the graph using the output of another callback.

Here is the code for the graph and for the dropdowns callback. I would really appreciate some help since I have been spending a lot of time searching for a solution.

fig_costs = go.Figure()

for i in range(0, 4):
    fig_costs.add_trace(go.Scatter(
        x=x_data,
        y=y_data_cost[i], mode='lines+markers',
        name=labels_costs[i],
        line=dict(color=colors[i], width=line_size[i]),
        connectgaps=True,
        ))


fig_costs.update_layout(
    xaxis=dict(
        showline=True,
        showgrid=False,
        showticklabels=True,
        linecolor='rgb(204, 204, 204)',
        linewidth=2,
        ticks='outside',
        tickfont=dict(
            family='Arial',
            size=12,
            color='rgb(82, 82, 82)',
        ),
    ),
    yaxis=dict(
        showgrid=False,
        zeroline=False,
        showline=False,
        showticklabels=False,
    ),
    autosize=True,
    margin=dict(
        autoexpand=False,
        l=100,
        r=20,
        t=110,
    ),
    showlegend=False,
    plot_bgcolor='white'
)

annotations = []

# Adding labels
for y_trace, label, color in zip(y_data_cost, labels_costs, colors):
    # labeling the left_side of the plot
    annotations.append(dict(xref='paper', x=0.05, y=y_trace[0],  # hier stand 0 (?)
                            xanchor='right', yanchor='middle',
                            text=label,
                            font=dict(family='Arial',
                                      size=16),
                            showarrow=False))
    # labeling the right_side of the plot
    annotations.append(dict(xref='paper', x=0.95, y=y_trace[11],  # hier stand 11
                            xanchor='left', yanchor='middle',
                            text='{} $'.format(y_trace[11]),  # hier stand 11
                            font=dict(family='Arial',
                                      size=14),
                            showarrow=False))

# Title chart costs
annotations.append(dict(xref='paper', yref='paper', x=0.0, y=1.05,
                        xanchor='left', yanchor='bottom',
                        text='',
                        font=dict(family='Arial',
                                  size=30,
                                  color='rgb(37,37,37)'),
                        showarrow=False))

fig_costs.update_layout(annotations=annotations)

layout = html.Div([
                html.H1('Costs'),
                dcc.Dropdown(
                    id='dropdown-category',
                    options=[{'label': option, 'value': option}
                             for option in dropdown_options],
                    value=list(dropdown_options.keys())[0],
                    placeholder="Select vehicle category",
                ),
                dcc.Dropdown(
                    id='id-dropdown',
                    options=[{'label': i, 'value': i}
                             for i in df_cost_data.vid.unique()],
                    placeholder="Select vehicle id",
                ),

                html.Div(id='display-selected-values'),
                dcc.Graph(id='costs-chart',
                          figure=fig_costs
                          ),
            ], className='card'), width=True),
        ])
# callback dropdown
@app.callback(
    Output('id-dropdown', 'options'),
    [Input('dropdown-category', 'value')]
)
def update_dropdown(option):
    return [{'label': i, 'value': i} for i in dropdown_options[option]]

# callback to filter the graph (not working)
@app.callback(
    Output('costs-chart', 'figure'),
    [Input('dropdown-category', 'value'),
     Input('id-dropdown', 'value')])
def update_chart(selected_id):
    traces = []
    if selected_id is None:
        filtered_df = df_cost_data[df_cost_data['vid'] == 'value']
        go.Scatter(
            x=x_data,
            y=filtered_df['total_cost']
        )
    else:
        filtered_df = df_cost_data[df_cost_data['vid'] == 'value']
        traces.append(
                go.Scatter(
                    x=x_data,
                    y=filtered_df['fuel_cost_total']
                    )
        )
    figure = {'data': traces, 'layout': layout}
    return figure

Thank you!!

Larisa