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:
- 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)
- Also tried curdoc().clear() in the above. Same result as above.
- 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.