The bokeh server plot is updated when the reading of all datapoints is finished.
I would like to have the datapoints updated one by one, as soon as they are available from a file stream.
I have code in MVC style:
The controller opens the filestream, reads a line from file, parses it and gives it to view.
The view creates a simple bokeh plot, by using a ColumnDataSource
.
As soon as the controller calls the update function, the new data is streamed to the plot.
from bokeh.models import ColumnDataSource
from bokeh.plotting import figure, curdoc
class View:
def __init__(self):
self.count = 0
self.source = ColumnDataSource(dict(x=[], y=[]))
self.p = figure(
plot_width=900,
plot_height=600)
self.p.line(x='x', y='y', source=self.source)
curdoc().add_root(self.p)
def update(self, data):
self.count += 1
new_data = dict(
x=[self.count],
y=[data])
self.source.stream(new_data)
Does anyone have an example or a hint where it is done one by one instead of all together? I already tried to add a periodic callback and in general follow the example from bokeh's gallery OHLC
(https://github.com/bokeh/bokeh/tree/master/examples/app/ohlc).
I think reason might be, that the callback must come from an interaction with the interface and not from inside the code. Both pressing a button to update or to have a periodic callback would do this. Adding periodic callback like so curdoc().add_periodic_callback(self.update, 1)
does not help, although. Second idea is that the underlying process of reading blocks the plotting. Other bokeh applications I wrote, where a button was pressed, e.g., did not have this problem. Alas, here, the plot is only available when all reading in is finished.
Many thanks!
Edit: The controller's code:
from model import Model
from view import View
class Controller:
def __init__(self, filename):
self.model = Model()
self.view = View()
with open(filename) as file:
for self.line in file:
self.request_data_from_model()
self.send_data_to_view()
def request_data_from_model(self):
return self.model.read(self.line)
def send_data_to_view(self):
self.view.update(self.request_data_from_model())