☰Read-only archive⌕
Looking for help with Bokeh?

This is a read-only archive. Ask questions and join the conversation on GitHub.

Visit Community Support on GitHub →
Archived discussions · Captured October 28, 2026

Update tab 1 based on selection made in tab 2 (Bokeh 1.0.0)

Community Support
dw457
dw457

In main.py, I create the document using: (I run this using bokeh serve --show main.py)

tabs = Tabs(tabs = [tab1,tab2,tab3])

curdoc().add_root(tabs) #output looks like [Tabs(id…)]

Here, each tab is creating using something like:

tab1 = Panel(child = init_tab_layout, title = “Tab1 View”, name = ‘tab1’)

tab2 = Panel(child = layout, title = “Tab2 View”, name = ‘tab2’)

I have a button in tab2 that takes in the selection of network nodes in a figure on tab2 and should update the layout (figures) of tab1 based on this selection.

I’ve tried a number of things, including:

  1. Creating a completely new tab1 and resetting the root completely. The document is cleared in the browser but not replaced (even though I confirmed that curdoc() has the new tabs in it using curdoc().roots[0]).

tab1 = Panel(child = new_layout, title = “Tab1 View”, name = ‘tab1’)

tab2 = curdoc().select_one({“name”:“tab2”}, name = “tab2”)

tabs = Tabs(tabs = [tab1,tab2])

curdoc().remove_root(curdoc().roots[0])

curdoc().add_root(tabs)

  1. Also tried curdoc().clear() in the above. Same result as above.

  2. Attempted to change the the children of the panel for tab1: Again, the tabs in curdoc() are updated but no change is shown in the server.

pan = curdoc().select_one({“name”:“tab2”}).child

pan.children = new_layout.children

Would appreciate any help on changing one tab based on selections in another tab, and having these changes actually show up in the browser. Thank you in advance.

⌁   Link to post
tony12624120
tony12624120

If you want to keep existing plots on the first tab and only re-draw the data there than you could just swap the plot datasources like this (run with bokeh serve --show app.py, Python 3.5, Bokeh 1.0.4):

from bokeh.layouts import Column, Row
from bokeh.models import CustomJS, ColumnDataSource
from bokeh.plotting import figure, curdoc, show
from bokeh.models.widgets import Button, Tabs, Panel
import numpy as np

tabs_array =
data = [dict(x = np.arange(10), y = np.random.random(10)) for counter in range(1, 5)]
data_sources = [ColumnDataSource(dict(x = np.arange(10), y = np.random.random(10))) for counter in range(1, 3)]

def button_callback():
for index in range(2):
data_sources[index].data = data[index + 2]

button = Button(label = ‘Swap DataSource’, width = 100)

def get_plots():
row = Row()
plots = [figure(plot_height = 400, tools = ‘’) for i in range(2)]
[plot.line(x = ‘x’, y = ‘y’, source = data_sources[index]) for index, plot in enumerate(plots)]
[row.children.append(plot) for plot in plots]
return row

def make_tab(tab_nmb):
if tab_nmb:
return Panel(title = ‘{name}’.format(name = tab_nmb), child = button)
else:
return Panel(title = ‘{name}’.format(name = tab_nmb), child = get_plots())

[tabs_array.append(make_tab(tab_nmb)) for tab_nmb in range(2)]
tabs = Tabs(tabs = tabs_array)

def get_callback(val):
return CustomJS(args = dict(val = val, tabs = tabs), code = “”"
if (val < 0)
tabs.active = tabs.active + val > -1 ? tabs.active + val : tabs.tabs.length -1;
if (val > 0)
tabs.active = tabs.active + val < tabs.tabs.length ? tabs.active + val : 0;“”")

button.callback = get_callback(-1)
button.on_click(button_callback)

document = curdoc()
document.add_root(tabs)
show(tabs)

``

If you want to replace entire plots or change their number I would go for “children.remove()” than “children.append()” on the Row/Column/Gridplot object inside the tab.

Please always post a minimal but complete and runnable code to reproduce your case.

Thanks

···

On Wednesday, February 13, 2019 at 9:34:52 PM UTC+1, Dana Warmsley wrote:

In main.py, I create the document using: (I run this using bokeh serve --show main.py)

tabs = Tabs(tabs = [tab1,tab2,tab3])

curdoc().add_root(tabs) #output looks like [Tabs(id…)]

Here, each tab is creating using something like:

tab1 = Panel(child = init_tab_layout, title = “Tab1 View”, name = ‘tab1’)

tab2 = Panel(child = layout, title = “Tab2 View”, name = ‘tab2’)

I have a button in tab2 that takes in the selection of network nodes in a figure on tab2 and should update the layout (figures) of tab1 based on this selection.

I’ve tried a number of things, including:

  1. Creating a completely new tab1 and resetting the root completely. The document is cleared in the browser but not replaced (even though I confirmed that curdoc() has the new tabs in it using curdoc().roots[0]).

tab1 = Panel(child = new_layout, title = “Tab1 View”, name = ‘tab1’)

tab2 = curdoc().select_one({“name”:“tab2”}, name = “tab2”)

tabs = Tabs(tabs = [tab1,tab2])

curdoc().remove_root(curdoc().roots[0])

curdoc().add_root(tabs)

  1. Also tried curdoc().clear() in the above. Same result as above.
  1. Attempted to change the the children of the panel for tab1: Again, the tabs in curdoc() are updated but no change is shown in the server.

pan = curdoc().select_one({“name”:“tab2”}).child

pan.children = new_layout.children

Would appreciate any help on changing one tab based on selections in another tab, and having these changes actually show up in the browser. Thank you in advance.

⌁   Link to post
dw457
dw457

This helped quite a bit. Thank you!

···

On Wednesday, February 13, 2019 at 3:39:44 PM UTC-8, tony halik wrote:

If you want to keep existing plots on the first tab and only re-draw the data there than you could just swap the plot datasources like this (run with bokeh serve --show app.py, Python 3.5, Bokeh 1.0.4):

from bokeh.layouts import Column, Row
from bokeh.models import CustomJS, ColumnDataSource
from bokeh.plotting import figure, curdoc, show
from bokeh.models.widgets import Button, Tabs, Panel
import numpy as np

tabs_array =
data = [dict(x = np.arange(10), y = np.random.random(10)) for counter in range(1, 5)]
data_sources = [ColumnDataSource(dict(x = np.arange(10), y = np.random.random(10))) for counter in range(1, 3)]

def button_callback():
for index in range(2):
data_sources[index].data = data[index + 2]

button = Button(label = ‘Swap DataSource’, width = 100)

def get_plots():
row = Row()
plots = [figure(plot_height = 400, tools = ‘’) for i in range(2)]
[plot.line(x = ‘x’, y = ‘y’, source = data_sources[index]) for index, plot in enumerate(plots)]
[row.children.append(plot) for plot in plots]
return row

def make_tab(tab_nmb):
if tab_nmb:
return Panel(title = ‘{name}’.format(name = tab_nmb), child = button)
else:
return Panel(title = ‘{name}’.format(name = tab_nmb), child = get_plots())

[tabs_array.append(make_tab(tab_nmb)) for tab_nmb in range(2)]
tabs = Tabs(tabs = tabs_array)

def get_callback(val):
return CustomJS(args = dict(val = val, tabs = tabs), code = “”"
if (val < 0)
tabs.active = tabs.active + val > -1 ? tabs.active + val : tabs.tabs.length -1;
if (val > 0)
tabs.active = tabs.active + val < tabs.tabs.length ? tabs.active + val : 0;“”")

button.callback = get_callback(-1)
button.on_click(button_callback)

document = curdoc()
document.add_root(tabs)
show(tabs)

``

If you want to replace entire plots or change their number I would go for “children.remove()” than “children.append()” on the Row/Column/Gridplot object inside the tab.

Please always post a minimal but complete and runnable code to reproduce your case.

Thanks

On Wednesday, February 13, 2019 at 9:34:52 PM UTC+1, Dana Warmsley wrote:

In main.py, I create the document using: (I run this using bokeh serve --show main.py)

tabs = Tabs(tabs = [tab1,tab2,tab3])

curdoc().add_root(tabs) #output looks like [Tabs(id…)]

Here, each tab is creating using something like:

tab1 = Panel(child = init_tab_layout, title = “Tab1 View”, name = ‘tab1’)

tab2 = Panel(child = layout, title = “Tab2 View”, name = ‘tab2’)

I have a button in tab2 that takes in the selection of network nodes in a figure on tab2 and should update the layout (figures) of tab1 based on this selection.

I’ve tried a number of things, including:

  1. Creating a completely new tab1 and resetting the root completely. The document is cleared in the browser but not replaced (even though I confirmed that curdoc() has the new tabs in it using curdoc().roots[0]).

tab1 = Panel(child = new_layout, title = “Tab1 View”, name = ‘tab1’)

tab2 = curdoc().select_one({“name”:“tab2”}, name = “tab2”)

tabs = Tabs(tabs = [tab1,tab2])

curdoc().remove_root(curdoc().roots[0])

curdoc().add_root(tabs)

  1. Also tried curdoc().clear() in the above. Same result as above.
  1. Attempted to change the the children of the panel for tab1: Again, the tabs in curdoc() are updated but no change is shown in the server.

pan = curdoc().select_one({“name”:“tab2”}).child

pan.children = new_layout.children

Would appreciate any help on changing one tab based on selections in another tab, and having these changes actually show up in the browser. Thank you in advance.

⌁   Link to post

End of archived discussion · Replies are disabled