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

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.

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.

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.

Hello,
I have the same problem.
The server is interpreted -> curdoc().remove_root(curdoc().roots[0]) -> The document is cleared in the browser.
but the new tab does not appear…

Would appreciate any help

@Ronit_Ben-Shalom It’s generally hard to advise on revivals of old threads. It’s too hard to disentangle what is current and relevant, from what is not. Please make a new topic with a complete, minimal reproducer for best results.