Question about Bokeh events

Hi - I am using Python, Angular, and Bokeh for the visualization project. I would like to know if it is possible to have the events that do the following - Let’s say I have a bar chart and there are 5 bars. If I click on any of the bar, it should open another chart (something like a further breakdown of the data from the bar). I hope my question is clear.

Could you please let me know if Bokeh provides such a feature?

Thanks,
Chetan

If you were to use a layout (e.g. a simple column), you could click on your glyph and have it update the children of that layout with whatever corresponding plot you intend.

This thread might be helpful.

1 Like

Hi @carolyn - This is what I was looking for. Thanks a lot!

I looked into an example, you provided here in this thread. Is it possible to hide child figures until the event has been triggered. For example, child figures should be visible only when I clicked on the first plot. Could you please let me know.

from bokeh.plotting import figure, show
from bokeh.models import ColumnDataSource, CustomJS
from bokeh.layouts import row

a = [0, 1, 2]
b = [5, 7, 2]
colors = ["orange", "green", "purple"]
main_fig_cds = ColumnDataSource(data={'a': a, 'b': b, 'colors': colors})

x =  [0, 1, 2, 3, 4, 5, 6]
y0 = [5, 2, 5, 2, 7, 3, 5]
y1 = [1, 3, 2, 4, 3, 5, 4]
y2 = [9, 6, 8, 3, 5, 9, 8]

main_fig = figure(tools="tap")
child_figs = [figure(title="Child 0"), figure(title="Child 1"), figure(title="Child 2")]
my_row = row(main_fig, child_figs[0])

change_child_callback = CustomJS(args=dict(my_row=my_row, child_figs=child_figs), code="""
  console.log(cb_obj.indices)
  // see https://discourse.bokeh.org/t/customjs-callback-to-modify-layout-organize-report/3777/2
  var children = [...my_row.children]
  children[1] = child_figs[cb_obj.indices[0]]
  my_row.children = children 
  """)

main_fig.circle(x='a', y='b', size=30, color='colors', source=main_fig_cds)
main_fig_cds.selected.js_on_change('indices', change_child_callback)
child_figs[0].line(x=x, y=y0, line_color="orange")
child_figs[1].line(x=x, y=y1, line_color="green")
child_figs[2].line(x=x, y=y2, line_color="purple")

show(my_row)

@carolyn Do you have any suggestions for my above question. Thanks!

You could do this by making the child initially an empty Div. Up in your imports, include Div:

from bokeh.models import ColumnDataSource, CustomJS, Div

And then when you first declare my_row on line 17, change the second argument to an empty Div:

my_row = row(main_fig, Div())

This will act as a placeholder until you start clicking on circles in the main plot.

Works like a charm!! Thanks a lot, @carolyn

1 Like

Hi @carolyn One follow-up question. The above code works fine in the Jupyter notebook and the bokeh server. How do I integrate this with Angular or other front ends? Do you have any suggestions on how it can be done?

Unfortunately, I do not. This is a problem I have tried to tackle myself in my day job, and I have not come up with a truly working solution. If you search the Discourse you’ll find several questions along this line, but as far as I know we do not have a good process for embedding in Angular.