简体   繁体   English

使用烧瓶和散景绘制实时数据

[英]Plotting realtime data with flask and bokeh

I am using a MongoDB to store sensordata(1 Measurement / sec.) and I would like to use flask and bokeh to plot the data in realtime in a web browser.我正在使用 MongoDB 来存储传感器数据(1 次测量/秒),我想使用 Flask 和 bokeh 在 Web 浏览器中实时绘制数据。 Unfortunately my knowledge regarding web-frameworks is not that good.不幸的是,我对网络框架的了解并不是那么好。 So far I managed to create a static plot which reads the data from the database (see example below) What would be the best way to update the plot in realtime?到目前为止,我设法创建了一个从数据库中读取数据的静态图(请参见下面的示例)实时更新图的最佳方法是什么?

from flask import Flask

import datetime
from pymongo import MongoClient
from bokeh.templates import RESOURCES

from bokeh.plotting import figure
from bokeh.resources import CDN
from bokeh.embed import file_html

app = Flask(__name__)

@app.route('/')
def index():
    client = MongoClient()

    db = client.test
    sdata = db.sensordata

    output = list(sdata.find())

    temp = [x['temperature'] for x in output]

    get_time = lambda x: datetime.datetime.strptime(x['time'], '%Y-%m-%d %H:%M:%S')
    time = [get_time(x) for x in output]

    humidity = [x['humidity'] for x in output]
    plot = figure(x_axis_type = "datetime")
    plot.line(time, temp)
    plot.line(time, humidity)

    html = file_html(plot, CDN, "my plot")

    return html

if __name__=='__main__':
    app.run(host='localhost', debug=True)

EDIT:编辑:

I think a solution with flask-socketio would be nice, but im not yet sure how to do it.我认为使用flask-socketio 的解决方案会很好,但我还不确定该怎么做。 To embedd the plot I need to create a script and div with script, div = components(plot) see ( http://docs.bokeh.org/en/latest/docs/user_guide/embed.html ) So the script is put into the html header while the div is put into the body.要嵌入绘图,我需要创建一个脚本和带有script, div = components(plot)见( http://docs.bokeh.org/en/latest/docs/user_guide/embed.html )所以脚本被放置将 div 放入正文时放入 html 标题中。 I don't see how to update the data since it is stored inside script file in the header and not in the div.我不知道如何更新数据,因为它存储在标头中的脚本文件中,而不是在 div 中。 My Idea was to change the html in the div with :我的想法是使用以下内容更改 div 中的 html:

 <script type="text/javascript" charset="utf-8">
    $(document).ready(function(){
        //connect to the socket server.
        var socket = io.connect('http://' + document.domain + ':' + location.port + '/');

        socket.on('plotupdate', function(msg) {
            $('#plot').html(msg.plot);
        });

    });
</script>

But this doesn't work in this case.但这在这种情况下不起作用。

You can use javascript's setInterval with an ajax call to refresh only a div that contains the plot.您可以将 javascript 的 setInterval 与 ajax 调用结合使用,以仅刷新包含绘图的 div。 Change your route to something like "/plotIt".将您的路线更改为“/plotIt”之类的内容。 Showing code using jQuery for a repeated ajax call refreshing a div with id="myPlot" attribute:显示使用 jQuery 进行重复 ajax 调用刷新具有 id="myPlot" 属性的 div 的代码:

setInterval(function() {
      $.ajax({
        url: "/plotit",
        type: "GET",
        dataType: "html",
        success: function (data) {$('#myPlot').html(data);},
    });
}, 60*1000); // Repeat interval is in milliseconds

Haven't tested this code, but it should work OK or with little tweaking.尚未测试此代码,但它应该可以正常工作或稍作调整。

I'm usually not a huge fan of repeated jobs like this and prefer a more event-driven approach.我通常不太喜欢这样的重复工作,更喜欢事件驱动的方法。 Namely, using an event listener for new sensor data (listening on mongodb) and pushing a new plot (using eg flask-socketio ) when a new plot has generated.即,使用事件侦听器获取新的传感器数据(在 mongodb 上侦听)并在生成新图时推送新图(使用例如flask-socketio )。 Choose whichever approach works for you.选择适合您的方法。 Above code should at least get you started.上面的代码至少应该让你开始。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM