Change a second plot by clicking glyph

Hello,
I feel like this should be straightforward but I haven’t found the method yet. I would like to produce a standalone page showing 2 plots. Plot 1 is a bar chart and when an individual bar is clicked, plot 2 would change to a corresponding plot. Is there an existing bokeh technique that would do this or do I need a CustomJS callback?
Thanks

@RobM

What you’re describing at a high-level seems most similar to the bokeh framework for selection events. As you want a standalone document, you will need to write callbacks in JavaScript for the specific actions that happen when a selection is made.

As a starting point see the CustomJS for Selections of the bokeh user’s guide. It is towards the bottom of the callbacks page at the following URL and includes several examples of selection events; although none are exactly your use case, it should provide a good starting point …

1 Like

@RobM ,

Everything @_jm said, plus here is an example! There’s a non-obvious approach to changing the layout child in the CustomJS, so I thought this might be useful (see this thread for background info).

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)
2 Likes