Select whole column(bar) in stacked bar chart

Hi,

I am using stacked bar charts in my dashboard. They look relatively simple:

Now, I would like use to be able to select column. However, when I click on the graph I can select only particular cell of the not the whole bar (in the sample below, pink cell in the bar on the right is selected):

Is there any to change this behavior? I would love whole bar to have full bright color.

Hi @Hikari,

What is the reason for your selection, i.e. what do you want to spend with it?

Hi,

Depending on selection on I will have different data displayed on another graphs. However, I have no interest in particular cell of a column, but the full column.

Plotly, any ideas how to select whole bar instead of its piece only?

Hi @Hikari, actually what you are asking for should be an easy task. Because of that, my solution feels wrong: can it really be that complicated to achieve what you want to do?

Anyways, a complicated solution might be preferable over no sloution at all, so here it comes:

I use the click event to get the information, which column has been clicked (clicked_point) and use this information for “selecting” all traces at the clicked point.

The code:

from dash import Dash, html, dcc, Input, Output, State
import plotly.express as px

app = Dash(__name__)

# data
df = px.data.medals_long()

# base figure
fig = px.bar(
    df,
    x="medal",
    y="count",
    color="nation",
    pattern_shape="nation",
    pattern_shape_sequence=[".", "x", "+"]
)

# update clickmode events, enable click event only
fig.update_layout(clickmode='event')

# app layout ( just the graph)
app.layout = html.Div(
    [
        dcc.Graph(
            id='graph',
            figure=fig
        )
    ]
)


@app.callback(
    Output('graph', 'figure'),
    Input('graph', 'clickData'),
    State('graph', 'figure'),
    prevent_initial_call=True
)
def update(data, current_figure):
    # which point has been clicked?
    clicked_point = data["points"][0]["pointIndex"]

    # extract traces
    traces = current_figure['data']

    # loop over all traces
    for idx, trace in enumerate(traces):

        # update selection state of the clicked point in the trace dict
        trace.update({'selectedpoints': [clicked_point]})

        # update figure dict with updated trace dict
        current_figure['data'][idx].update(trace)

    return current_figure


if __name__ == "__main__":
    app.run(debug=True)

result:
bars

Looks like a solution! Thank you.