用django和bokeh绘制实时数据的正确方法

[英]Right way to plot live data with django and bokeh


i have a bokeh plot embedded in a django app. I create the plot in the django view and push the plot to the bokeh server to show the plot in my webpage.

我在django应用程序中嵌入了一个bokeh图。我在django视图中创建了这个图,并将它推送到bokeh服务器,在我的页面中显示这个图。

#view.py
def view_plot(request):
    f=figure()
    f.plot(#some data#)
    session = push_session(curdoc())
    context = {'script': autoload_server(f, session_id=session.id)}
    return render_to_response('plot.html', context=context)

It all works quite good. Now I want to do a live plot, every time when a new DB-Entry is created the plot should be updated. I'm not sure what is the best way.

这一切都很好。现在我想做一个活的情节,每次创建一个新的DB-Entry时,这个情节都应该被更新。我不知道最好的办法是什么。

Is it a good practice to use a timer on the webpage to ask for now data?

在网页上使用定时器来要求现在的数据是一个好的做法吗?

Or is there a way to push the update form the server so that every currently connected client gets the plot update?

或者有没有一种方法可以将更新表单推送到服务器,以便每个当前连接的客户端都能获得情节更新?

I would be very thankful for every hint.

我会非常感谢每一个暗示。

Thanks a lot.

非常感谢。

3 个解决方案

#1


4  

Basically your problem here is that browsers use a request-response pattern: they send a request and then get back an answer immediately. You have two options, polling the server periodically or some kind of notification system.

基本上,这里的问题是浏览器使用请求-响应模式:它们发送请求,然后立即返回一个响应。您有两个选项,定期轮询服务器或某种通知系统。

Notifications could be long-polling, i.e. client makes a request and server doesn't respond until there's data, or through websockets or through HTML5 server-side events.

通知可以是长轮询,即客户端发出请求,服务器直到有数据,或者通过websockets或者通过HTML5服务器端事件才作出响应。

Now, the thing is that these notification systems don't integrate too well with a traditional Django deployment, since they result in an open socket and a corresponding hanging thread. So if your webserver has 10 Django threads, one browser with 10 tabs could tie up all of them.

现在,问题是这些通知系统不能很好地与传统的Django部署集成,因为它们导致一个打开的套接字和一个相应的挂起线程。因此,如果您的web服务器有10个Django线程,那么一个带有10个选项卡的浏览器就可以将所有这些线程绑定在一起。

Work is underway to change that, but in the mean time, unless you have a hard real-time requirement or lots of clients, just set a timer and poll every x seconds, where x depends on what latency is acceptable. Depending on how your data is stored, I would probably put in a simple mechanism so that the server doesn't send the whole dataset each time, but only either what's new or a carry-on-nothing-changed return code.

工作正在进行改变,但同时,除非你有一个硬的实时需求或大量的客户端,只要设置一个定时器和轮询每一个x秒,其中x依赖于什么延迟是可以接受的。根据您的数据是如何存储的,我可能会放入一个简单的机制,这样服务器就不会每次都发送整个数据集,而是只发送新数据或不做任何修改的返回代码。

For instance, on the first request, the server may put in a timestamp or serial number in the response, and then the client asks for any changes since that timestamp/serial number.

例如,在第一个请求中,服务器可能在响应中输入时间戳或序列号,然后客户端请求从该时间戳/序列号开始进行任何更改。

A notification system gives you better latency with lower overhead, but it is probably also going to be more difficult to deploy, and will probably be overkill if this is just an app for internal use. Even with a notification system, you need to do some careful protocol design to be sure not to miss something.

通知系统提供了更好的延迟和更低的开销,但是它也可能更难于部署,如果这只是一个用于内部使用的应用程序,那么它可能会被过多地占用。即使使用通知系统,您也需要进行一些仔细的协议设计,以确保不会漏掉某些内容。

#2


3  

In my opinon it's okay to use something like a heartbeat-timer in your frontend which triggers a data fetch every second or so. Especially if you implemented caching on the backend.

在我的opinon中,可以在前端使用像心跳计时器这样的东西来触发每一秒的数据读取。特别是在后台实现缓存时。

A more sophisticated version could use something like django channels to handle the communication via web sockets.

更复杂的版本可以使用django通道之类的东西通过web套接字处理通信。

I would say it depends on the maturity of the project.

我认为这取决于项目的成熟度。

#3


1  

Something like this worked for me:

像这样的东西对我起了作用:

#views.py
from bokeh.plotting import figure, curdoc
from bokeh.client import pull_session

def my_line_chart(request):
    session = pull_session(url = "http://localhost:5006/myapp")
    bokeh_script=autoload_server(None,url = "http://localhost:5006/myapp", session_id= session.id)
    return render(request, u'line_charts.html', {u'the_script': bokeh_script})

Then on your bokeh server use source.stream()

然后在您的bokeh服务器上使用source.stream()

    #myapp
    '''
    everything else here
    '''
    def update():
        new_data = qu() #qu is the newdata to be updated
        source.stream(new_data, rollover = 60)
        print(source.data) #if you want to see new data

    curdoc().add_root(p)
    curdoc().add_periodic_callback(update,10000)

then start your bokeh server and allow connection from django like

然后启动bokeh服务器并允许从django进行连接

bokeh serve --allow-websocket-origin=127.0.0.1:8000 myapp.py #you can add app2.py too

I used port 8000 because that is my django port, and port 5006 on views.py because it is my tornado port.

我使用端口8000,因为那是我的django端口,在视图上是端口5006。因为那是我的龙卷风港口。

Check class columndatasource for more

检查类columndatasource以获得更多信息

Hope it helps.

希望它可以帮助。


注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:http://www.silva-art.net/blog/2016/04/24/9a93a66ac314dc366c004a0d2f2ae234.html



 
© 2014-2019 ITdaan.com 粤ICP备14056181号