Refresh Bokeh 0.12.6 chart with streaming data from Flask

Fight with Bokeh and Flask to display data from streaming.

Updating the data source is planned and not controlled by Bokeh (I see that this is done every second).

How to force a graph to be updated (perhaps not the whole page, since there are several graphs in the final version)?

Here is a cut and executable version of the faulty code. Any idea is welcome.

# -*- coding: utf-8 -*-

import numpy as np
import pandas as pd

from bokeh.embed import components
from bokeh.plotting import figure
from bokeh.resources import INLINE
from bokeh.models.sources import ColumnDataSource

from flask import Flask, render_template_string
from flask_apscheduler import APScheduler
from apscheduler.triggers.interval import IntervalTrigger

html_template = """
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        {{ js_resources | safe }}
        {{ css_resources | safe }}
    </head>
    <body>
        <div>
            {{ plot_div.graph_1 | safe }}
        </div>

        {{ plot_script | safe }}
    </body>
</html>
"""
resources = INLINE
js_resources = resources.render_js()
css_resources = resources.render_css()

app = Flask(__name__)

@app.route("/")
def main_graph():

    script, div = components({'graph_1': graph_1.figure,})

    return  render_template_string(html_template,
        js_resources=js_resources,
        css_resources=css_resources,
        plot_script=script,
        plot_div=div)

# -------------------------------------------------------------------------------------------------------------------


class Generic3Lines:

    def __init__(self, scheduler):

        self.data_source = ColumnDataSource()

        self.figure = figure()
        self.figure.axis.visible = True

        self.update_data()

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

        scheduler.add_job(id="scheduled_update", func=self.update_data, trigger=IntervalTrigger(seconds=1))

    def update_data(self):

        df = pd.DataFrame(dict(
            date_time = range(180),
            "value_1" = np.random.random(size=180)*5+5,
            "value_2" = np.random.random(size=180)*5+10,
            "value_3" = np.random.random(size=180)*5+15,
        ))

        print(df.head(1))

        self.data_source = dict(date_time=df["date_time"],
                                 value_1=df["value_1"],
                                 value_2=df["value_2"],
                                 value_3=df["value_3"],
                                 )

scheduler = APScheduler()
scheduler.start()

graph_1 = Generic3Lines(scheduler=scheduler)

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5050)
+4
source share

Source: https://habr.com/ru/post/1682490/


All Articles