@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)