See the code below.
I have a loop that creates 3 tabs on 1 DataTable and 1 RangeSlider.
I want all 3 tabs to update when I use the slider, but unfortunately only the last tab updates.
It probably has something to do with the iteration because it’s the last tab always, but I can’t wrap my head around how to make it work.
from bokeh.models.widgets import DataTable, DateFormatter, TableColumn, Panel, Tabs, RangeSlider
from bokeh.io import output_file, show
from bokeh.models import ColumnDataSource, Div
from bokeh.plotting import curdoc
from bokeh.plotting import figure
from bokeh.layouts import layout, widgetbox, row, column
from datetime import date
from random import randint
import pandas as pd
from os.path import dirname, join
df1 = pd.DataFrame(
{'x': [date(2014, 3, i+1) for i in range(10)],
'y': [randint(0, 100) for i in range(10)],
'z': [randint(0, 50) for i in range(10)],
'q': ['B' for i in range(10)]
})
df2 = pd.DataFrame(
{'x': [date(2014, 3, i+1) for i in range(10)],
'y': [randint(0, 100) for i in range(10)],
'z': [randint(0, 50) for i in range(10)],
'q': ['A' for i in range(10)]
})
df3 = pd.DataFrame(
{'x': [date(2014, 3, i+1) for i in range(10)],
'y': [randint(0, 100) for i in range(10)],
'z': [randint(0, 50) for i in range(10)],
'q': ['A' for i in range(10)]
})
value_slider = RangeSlider(title="Value", range =(0,100), start=0, end=100, step=1)
tab_list = []
for df in [df1, df2, df3]:
source = ColumnDataSource(data=dict(
x=df['x'],
y=df['y'],
z=df['z']
))
columns = [
TableColumn(field="x", title="Date", formatter=DateFormatter()),
TableColumn(field="y", title="Downloads"),
TableColumn(field="z", title="Z"),
]
data_table = DataTable(source=source, columns=columns, width=400, height=280)
tab = Panel(child=data_table, title="table")
tab_list.append(tab)
def select():
selected = df[
(df['y'] >= value_slider.range[0]) &
(df['y'] <= value_slider.range[1])
]
return selected
def update():
df1 = select()
source.data = dict(
x = df1['x'],
y = df1['y'],
z = df1['z'],
)
tabs = Tabs(tabs=tab_list)
value_slider.on_change('range' ,lambda attr, old, new: update())
selectors = widgetbox(value_slider,width=200)
all_plot = row(column(selectors), tabs)
sizing_mode = 'fixed'
l = layout([[all_plot]], sizing_mode=sizing_mode)
curdoc().add_root(l)