1

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())

katya_ava
  • 65
  • 1
  • 7
  • "Other bokeh applications I wrote, where a button was pressed, e.g., did not have this problem." - this means, that there's some problem in your current app's code. Without having the full code, it's impossible to tell. But using `steam` with maybe a periodic callback should absolutely work for showing new data points as they become available. – Eugene Pakhomov Jun 01 '20 at 18:20
  • Thanks @EugenePakhomov. I will keep you updated. – katya_ava Jun 01 '20 at 18:53

0 Answers0