複数のグラフをWebブラウザのストリーミングデータから埋め込んで表示する必要があるクイックビジュアライゼーション。悲しいかな、私のJavascriptに関する知識は無く、私はこのテストの前にBokehを少し知っていると思っていましたが、私はそうではないようです。[Python + Bokeh + Flask]:フラスコ、複数のBokehグラフを埋め込んでリアルタイムストリーミングを視覚化する
私は非常に数多くの例がありますが、最後のBokehライブラリ(0.12.6)ではうまく動作しません。 既にStreaming two line graphs using bokehを見てきましたが、悲しいかなくFlaskを使用する必要があります。
私は問題を解決する適切な方向がであることを理解して、自分のコードを書き換えないようにします。
今まで私は解決策を見つけましたが、これは非常にCPUを消費しています(これは実用的なコードです、長さは申し訳ありません:私はすでにそれを取り除きました)。ここでも、グラフの代わりにページ全体がリフレッシュされます。 Chromium 58(Linux)では大丈夫ですが、Firefox 53(Linux)では非常に遅いです。
他のライブラリに変更するBokehはオプションです。フラスコは強制です。
app.py:
from bokeh.models import (FactorRange, LinearAxis, Grid, Range1d)
from bokeh.models.glyphs import Line
from bokeh.plotting import figure
from bokeh.embed import components
from bokeh.models.sources import ColumnDataSource
from flask import Flask, render_template
import random
app = Flask(__name__)
class SingleLine():
def __init__(self, color, elem_number):
self.color = color
self.elem_number = elem_number
self.data = {"time": [], "value": []}
for i in range(1, elem_number + 1):
self.data['time'].append(i)
self.data['value'].append(random.randint(1,100))
def create_line_plot(self, plot, x_name, y_name):
source = ColumnDataSource(self.data)
glyph = Line(x=x_name, y=y_name, line_color=self.color)
plot.add_glyph(source, glyph)
#----------------------------------------------------------------------------------
class CompleteGraph():
def __init__(self, lines_list, x_name, y_name, title, height=300, width=1000):
self.lines_list = lines_list
self.x_name = x_name
self.y_name = y_name
self.title = title
self.height = height
self.width = width
def create_graph(self):
xdr = FactorRange(factors=self.lines_list[0].data[self.x_name])
ydr = Range1d(start=0, end=max(self.lines_list[0].data[self.y_name]) * 1.5)
plot = figure(title=self.title, x_range=xdr, y_range=ydr,
plot_width=self.width, plot_height=self.height,
h_symmetry=False, v_symmetry=False,
tools=[],
responsive=True)
for l in self.lines_list:
l.create_line_plot(plot, self.x_name, self.y_name)
xaxis = LinearAxis()
yaxis = LinearAxis()
plot.add_layout(Grid(dimension=0, ticker=xaxis.ticker))
plot.add_layout(Grid(dimension=1, ticker=yaxis.ticker))
return components(plot)
@app.route("/")
def chart():
elem_number = 30
line1 = SingleLine(color="#ff0000", elem_number=elem_number)
line2 = SingleLine(color="#00ff00", elem_number=elem_number)
line3 = SingleLine(color="#00ff00", elem_number=elem_number)
# first graph
lines_list = [line1, line2]
lg1 = CompleteGraph(lines_list, "time", "value", "title graph 1")
# second graph
lines_list = [line1, line3]
lg2 = CompleteGraph(lines_list, "time", "value", "title graph 2")
script1, div1 = lg1.create_graph()
script2, div2 = lg2.create_graph()
return render_template("test_stackoverflow.html",
div1=div1, script1=script1,
div2=div2, script2=script2,
)
if __name__ == "__main__":
app.run(port=5000, debug=True)
とそれぞれのテンプレート:
test_stackoverflow.html
<html>
<head>
<style>
#wrapper { display: flex; }
#left { flex: 0 0 50%; }
#right { flex: 1; }
#wide { flex: 0 0 90% }
</style>
<title>Multiple realtime charts with Bokeh</title>
<link href="http://cdn.pydata.org/bokeh/release/bokeh-0.12.6.min" rel="stylesheet">
<link href="http://cdn.pydata.org/bokeh/release/bokeh-widgets-0.12.6.min.css" rel="stylesheet">
<script src="http://cdn.pydata.org/bokeh/release/bokeh-0.12.6.min.js"></script>
<script src="http://cdn.pydata.org/bokeh/release/bokeh-widgets-0.12.6.min.js"></script>
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script>
(function worker() {
$.ajax({
url: '/',
success: function(data) {
location.reload();
},
complete: function() {
// Schedule the next request when complete
setTimeout(worker, 1000);
}
});
})();
</script>
</head>
<body>
<div id="wrapper">
<div id="left">
<h1>left graph</h1>
{{ div1 | safe }}
{{ script1 | safe }}
</div>
<div id="right">
<h1>right graph</h1>
{{ div2 | safe }}
{{ script2 | safe }}
</div>
</div>
</body>
</html>
すべてのヘルプは大歓迎です。