Мой вопрос очень похож на another thread с использованием bokeh 0.7.1, но API для серверов bokeh изменился достаточно в 0.12.0, что я борюсь чтобы адаптировать этот ответ к новой версии.Динамическое добавление/удаление участка с использованием «bokeh serve» (bokeh 0.12.0)
Подводя итог, у меня есть страница с сеткой временного графика, потянув данные из файла, который постоянно обновляется. На странице есть меню MultiSelect, в котором перечислены все переменные в моем файле. Я хочу иметь возможность выбирать различные переменные в меню, нажимать кнопку, а затем отображать графики существующей переменной и заменяться новыми временными потоками, где количество графиков может отличаться. Я запускаю свой сценарий с помощью обертки bokeh serve --show script.py
.
В моей первоначальной попытке я назначил обработчик события кнопке, которая очищает «curdoc», а затем добавляет графики для вновь выбранных переменных из MultiSelect. Это выполняется, но количество графиков не обновляется. Очевидно, что мне не хватает вызова, который сообщает серверу как-то обновить макет страницы.
import numpy as np
from bokeh.driving import count
from bokeh.plotting import figure, curdoc
from bokeh.layouts import gridplot
from bokeh.models import Slider, Column, Row, ColumnDataSource, MultiSelect, Button
from netCDF4 import Dataset
import datetime
# data
#data = Dataset('/daq/spt3g_software/dfmux/bin/output.nc', 'r', format='NETCDF4')
data = Dataset('20160714_warm_overbiased_noise.nc', 'r', format='NETCDF4')
vars = data.variables.keys()[1:11]
# plots
d = {('y_%s'%name):[] for name in vars}
d['t'] = []
source = ColumnDataSource(data=d)
figs = [figure(x_axis_type="datetime", title=name) for name in vars]
plots = [f.line(x='t', y=('y_%s'%f.title.text), source=source, color="navy", line_width=1) for f in figs]
grid = gridplot(figs, ncols=3, plot_width=500, plot_height=250)
# UI definition
npoints = 2000
slider_npoints = Slider(title="# of points", value=npoints, start=1000, end=10000, step=1000.)
detector_select = MultiSelect(title="Timestreams:", value=[], options=vars)
update_detector_button = Button(label="update detectors", button_type="success")
# UI event handlers
def update_detector_handler():
global figs, plots, grid, source
d = {('y_%s'%name):[] for name in detector_select.value}
d['t'] = []
source = ColumnDataSource(data=d)
figs = [figure(x_axis_type="datetime", title=name) for name in detector_select.value]
plots = [f.line(x='t', y=('y_%s'%f.title.text), source=source, color="navy", line_width=1) for f in figs]
grid = gridplot(figs, ncols=3, plot_width=500, plot_height=250)
curdoc().clear()
curdoc().add_root(Column(Row(slider_npoints, Column(detector_select, update_detector_button)), grid))
update_detector_button.on_click(update_detector_handler)
# callback updater
@count()
def update(t):
data = Dataset('20160714_warm_overbiased_noise.nc', 'r', format='NETCDF4')
#data = Dataset('/daq/spt3g_software/dfmux/bin/output.nc', 'r', format='NETCDF4')
npoints = int(slider_npoints.value)
new_data = {('y_%s'%f.title.text):data[f.title.text][-npoints:] for f in figs}
new_data['t'] = data['Time'][-npoints:]*1e3
source.stream(new_data, npoints)
# define HTML layout and behavior
curdoc().add_root(Column(Row(slider_npoints, Column(detector_select, update_detector_button)), grid))
curdoc().add_periodic_callback(update, 500)
Любая идея, как это сделать для серверного приложения? Все ясно, но session.loop_until_closed(), похоже, не работает для боке. –
Похоже, что использование 'loop_until_closed()' теперь обескуражено: https://github.com/bokeh/bokeh/pull/7339 –