我需要在Web瀏覽器中以可視化的方式直觀顯示中的流式數據。唉,我對Javascript的知識是無效的,在測試之前我想知道一點點散景,但看起來我沒有。[Python + Bokeh + Flask]:Flask,嵌入多個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>
任何幫助是值得歡迎的。