Moje pytanie jest podobne do another thread przy użyciu bokeh 0.7.1, ale interfejs API dla serwerów bokeh zmienił się wystarczająco w 0.12.0, że walczę aby dostosować tę odpowiedź do nowej wersji.Dynamicznie dodawaj/usuwaj fabułę za pomocą "bokeh serve" (bokeh 0.12.0)
Podsumowując, mam stronę z siatką wykresów przebiegu czasowego, pobierającą dane z pliku, który jest ciągle aktualizowany. Strona zawiera menu MultiSelect, które zawiera listę wszystkich zmiennych w moim pliku. Chcę móc wybrać różne zmienne w menu, nacisnąć przycisk, a następnie znikną wykresy istniejącej zmiennej i zastąpić je nowymi strumieniami czasowymi, w których liczba wykresów może być inna. Używam skryptu o opakowaniu bokeh serve --show script.py
.
W mojej pierwszej próbie tego, przypisałem program obsługi zdarzeń do przycisku, który usuwa "curdoc", a następnie dodaje wykresy dla nowo wybranych zmiennych z MultiSelect. To działa, ale liczba działek nie aktualizuje się. Najwyraźniej brakuje mi połączenia, które mówi serwerowi, aby jakoś odświeżył układ strony.
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)
Każdy pomysł, jak to zrobić w przypadku aplikacji serwerowej? Wszystko jest jasne, ale session.loop_until_closed() nie działa w przypadku bokeh. –
Wygląda na to, że odradza się użycie 'loop_until_closed()': https://github.com/bokeh/bokeh/pull/7339 –