✊🏿 Black Lives Matter. Please consider donating to Black Girls Code today.
🧬 Learn how to build RNA-Seq data apps with Python & Dash. Register for the May 20 Webinar!

clickData for names of stacked barcharts

Hi All,

I was wondering whether it was possible to get the ‘name’ attribute of stacked bar charts. (or get acces to the entire trace)

In the example below I have a stacked barchart for two names (‘Ajax’ and ‘Feyenoord’), and when
the users clicks on the graph I would like to know whether they clicked on the Ajax or Feyenoord portion.

Instead the clickData output looks like this: { "points": [ { "curveNumber": 0, "pointNumber": 1, "pointIndex": 1, "x": 2, "y": 20 }, { "curveNumber": 1, "pointNumber": 1, "pointIndex": 1, "x": 2, "y": 30 } ] }, which both doesn’t show the name and simply shows the stack of datapoints for that stack of the barchart.

Code below.

import dash
from dash.dependencies import Input, Output, State
import dash_html_components as html
import dash_core_components as dcc

import json

import plotly.plotly as py
import plotly.graph_objs as go

app = dash.Dash(__name__)

data = [
    dict(x=[1,2], y=[10,20], name='Ajax', text='Ajax', type='bar'),
    dict(x=[1,2], y=[40,30], name='Feyenoord', test='Feyenoord', type='bar'),
]


layout = dict(title='test graph',
                  xaxis=dict(title='AB'),
                  yaxis=dict(title='number'),
                  barmode='relative',
                  showlegend=True)

fig = dict(data=data, layout=layout)


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

@app.callback(
    Output('clickData_out', 'children'),
    [Input('graph', 'clickData')])
def display_click_data(clickData):
    return json.dumps(clickData, indent=2)

if __name__ == '__main__':
    app.run_server(debug=True)

If you want the clickData to show the name of traces, it’s possible.
If you want to know which trace is clicked, then there probably isn’t a easy way.
change data to:

data = [
    dict(x=[1,2], y=[10,20], text=['Ajax', 'Ajax'], type='bar'),
    dict(x=[1,2], y=[40,30], text=['Feyenoord', 'Feyenoord'], type='bar'),
]

Then the output would be like:
{ "points": [ { "curveNumber": 0, "pointNumber": 0, "pointIndex": 0, "x": 1, "y": 10, "text": "Ajax" }, { "curveNumber": 1, "pointNumber": 0, "pointIndex": 0, "x": 1, "y": 40, "text": "Feyenoord" } ] }

So both “Ajax”, “Feyenoord” are in the clickData.

thanks! Although the idea would really be to be able to click on a particular trace and then get a further drilldown for that trace (in my actual app it’s not two, but more like 20-30 traces).

But maybe I can build it in a slightly different way in which I can drilldown based on the stack.

Hi oege,

I was looking for the same info… any progress you made and could share?

Thanks in advance

This helped me, for anyone that’s looking

1 Like

Finally got it to work!

  • @monishaj93 I can’t use app.layout[plot_id]. For me app.layout is a function, app.layout() is the home page, and anyway this seems unlikely to work for dynamic layouts/plots.

  • A possible related solution is from this post, to have the figure as a State of the callback then use the same figure['data'][curve_number]['name'] trick. Someone else just stumbledon this as well, code here

  • @caiyij I didn’t get any text in my clickData events at first (dash 1.10), but then found this related post and changed from text=df.columns[col] to text=[df.columns[col]] * df.index.size which made it work :slight_smile:
    The same is possible using customdata if you need to have another use for text.