How to highlight a single bar on select in Plotly Dash

I am building a dashboard with Plotly Dash. I have used the slider as input for the bar chart. I would like to use the dropdown to highlight a single country in the bar chart. The connection is shown by the yellow arrows in the picture.

I have used the ‘fig1.for_each_trace’ to connect it to the dropdown. It does not give an error, but does not what I want.

Can anyone help me out?

This link has put me in this direction: Creating And Updating Figures

The callback I have so far:

@app.callback(
    [
    Output('barchart-1', 'figure'),
    Output('year-1', 'children')
    ],
    Input('year-slider', 'value'),
    Input('dropdown-country', 'value')
    )
def update_visual(slctd_year, slctd_cntry):
    life = df1[df1['Year'] == slctd_year]
    country = df1[df1['Entity'] == slctd_cntry]

    fig1 = px.bar(
        life,
        x=life['Entity'],
        y=life['Life expectancy'],
        # template='simple white'
    )
    fig1.update_traces(marker_color='rgb(33, 60, 99)',
                       
    )

    fig1.update_layout(
            height= 315,
            margin=dict(l=20, r=30, t=50, b=30),
            plot_bgcolor='rgb(0,0,0,0)',
            legend_bgcolor='rgba(0,0,0,0)',
            paper_bgcolor='rgb(0,0,0,0)',
            font_color='#909090'
        )
    
    fig1.for_each_trace(
        lambda trace: trace.update(marker_color='#9D3469') if trace == country else (),
    )
2 Likes

Try setting marker_color to be a list of colors, one for each bar :slightly_smiling_face:

1 Like

Hi @StefanLS,

The issue with your approach is that px.bar generates a single trace with all the bars, so you can’t update individual bar colors looping over traces.

This is what I would use instead:

fig1["data"][0]["marker"]["color"] = ["red" if c == slctd_cntry else "blue" for c in fig1["data"][0]["x"]]

This assumes that you have a single trace in the figure (which is true in your OP example). The idea is simply to pass an array of colors to the trace and fig1["data"][0]["x"] contains the label to each bar.

Hope this helps!

2 Likes

Dang, @chriddyp beated me… :smile:

2 Likes

This works perfectly fine! Thanks.

Hi @jlfsjunior ,

How did you come to this:

thanks in advance.

You can find a complete explanation in the docs:

In a nutshell, fig["data"] is where the traces are defined. The color of each “graphic primitive” (bar, point, etc…) is defined in marker.color.

Is that what you are asking about?

1 Like

That is what I was asking about.
Thanks.

Thanks for sharing this information. It was useful.