Bokeh+Flask: Multiple AjaxDataSource calls

混江龙づ霸主 提交于 2019-12-24 19:23:48

问题


A Bokeh object is a figure that shows 3 indipendent lines.

Data are streamed. An AjaxDataSource call updates the data every 5 seconds reading the last ones from a database.

This is the stripped down class:

class Graph:
    def __init__(self):

        data_source = AjaxDataSource(data=dict(date_time=[],
                                               value_1=[], 
                                               value_2=[], 
                                               value_3=[]), 
                                               data_url="/data",
                                               polling_interval=5000)

        line1 = self.figure.line(x="date_time", y="value_1", source=data_source)
        line2 = self.figure.line(x="date_time", y="value_2", source=data_source)
        line3 = self.figure.line(x="date_time", y="value_3", source=data_source)

        app.add_url_rule("/data", "/data", self.serve, methods=['GET', 'OPTIONS', 'POST'])

    def serve(self):

        # load data from db and return JSON
        ...
        return jsonify(
            date_time= da.df["Date_Time"].tolist(),
            value_1=da.df["Value1"].tolist(),
            value_2=da.df["Value2"].tolist(),
            value_3=da.df["Value3"].tolist()
        )

date_time is the common x-axis, value_1 is for line 1, value_2 for line 2, value_3 for line 3.

The problem

Why is AjaxDataSource called 3 times (they are a few milliseconds apart, then the triple reading is done again after 5 seconds) instead of only once every 5 seconds?

I believed that AjaxDataSource fills dynamically data_source.data every 5 seconds and then, after they have been read, the 3 lines read these "now static" data.

Workaround?

Is there a way to read the data using AjaxDataSource, transfer automatically the data into a ColumnDataSource and use this as a "static" data source?

Or am I missing something important here?


回答1:


The issue is that each glyph that has a remote data source attached to it, tries to initialize the data source. In the case of AjaxDataSource, it doesn't check for previous initializations.

I've opened an issue for it: https://github.com/bokeh/bokeh/issues/6736

A temporary workaround that you could try:

Bokeh.require('models/sources/ajax_data_source').AjaxDataSource.prototype.setup = function () {
    this.get_data(this.mode);
    if (this.polling_interval && this.interval == null) {
        return this.interval = setInterval(this.get_data, this.polling_interval, this.mode, this.max_size, this.if_modified);
    }
}

Make sure that this code is run right after Bokeh is included in your page, but before it initializes its documents. How to do it depends on how you embed Bokeh.



来源:https://stackoverflow.com/questions/45301848/bokehflask-multiple-ajaxdatasource-calls

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!