Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/340.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 我可以在没有服务器回调的情况下更新bokeh图吗?_Python_Bokeh - Fatal编程技术网

Python 我可以在没有服务器回调的情况下更新bokeh图吗?

Python 我可以在没有服务器回调的情况下更新bokeh图吗?,python,bokeh,Python,Bokeh,我希望在python中运行的单独算法的结果返回结果时,Bokeh定期、任意地进行更新,而不是基于Bokeh接口的任何输入 我尝试过各种解决方案,但它们都依赖于对某个UI事件的回调或定期回调,如下面的代码所示 import numpy as np from bokeh.plotting import figure, curdoc from bokeh.models import ColumnDataSource, Plot, LinearAxis, Grid from bokeh.models.g

我希望在python中运行的单独算法的结果返回结果时,Bokeh定期、任意地进行更新,而不是基于Bokeh接口的任何输入

我尝试过各种解决方案,但它们都依赖于对某个UI事件的回调或定期回调,如下面的代码所示

import numpy as np
from bokeh.plotting import figure, curdoc
from bokeh.models import ColumnDataSource, Plot, LinearAxis, Grid
from bokeh.models.glyphs import MultiLine
from time import sleep
from random import randint


def getData():  # simulate data acquisition
    # run slow algorith
    sleep(randint(2,7)) #simulate slowness of algorithm
    return dict(xs=np.random.rand(50, 2).tolist(), ys=np.random.rand(50, 2).tolist())


# init plot
source = ColumnDataSource(data=getData())

plot = Plot(
    title=None, plot_width=600, plot_height=600,
    min_border=0, toolbar_location=None)

glyph = MultiLine(xs="xs", ys="ys", line_color="#8073ac", line_width=0.1)
plot.add_glyph(source, glyph)

xaxis = LinearAxis()
plot.add_layout(xaxis, 'below')

yaxis = LinearAxis()
plot.add_layout(yaxis, 'left')

plot.add_layout(Grid(dimension=0, ticker=xaxis.ticker))
plot.add_layout(Grid(dimension=1, ticker=yaxis.ticker))
curdoc().add_root(plot)


# update plot
def update():
    bokeh_source = getData()
    source.stream(bokeh_source, rollover=50)

curdoc().add_periodic_callback(update, 100)
这似乎是可行的,但这是最好的方法吗?与其让Bokeh尝试每100毫秒更新一次,我可以在数据可用时将新数据推送到它吗


谢谢

您可以使用zmq和asyncio来完成。以下是bokeh服务器的代码,它在异步协同路由中等待数据:

from bokeh.models import ColumnDataSource
from bokeh.plotting import figure, curdoc
from functools import partial
from tornado.ioloop import IOLoop
import zmq.asyncio

doc = curdoc()

context = zmq.asyncio.Context.instance()
socket = context.socket(zmq.SUB)
socket.connect("tcp://127.0.0.1:1234")
socket.setsockopt(zmq.SUBSCRIBE, b"")

def update(new_data):
    source.stream(new_data, rollover=50)

async def loop():
    while True:
        new_data = await socket.recv_pyobj()
        doc.add_next_tick_callback(partial(update, new_data))

source = ColumnDataSource(data=dict(x=[0], y=[0]))

plot = figure(height=300)
plot.line(x='x', y='y', source=source)

doc.add_root(plot)
IOLoop.current().spawn_callback(loop)
要发送数据,只需在另一个python进程中运行以下代码:

import time
import random
import zmq

context = zmq.Context.instance()
pub_socket = context.socket(zmq.PUB)
pub_socket.bind("tcp://127.0.0.1:1234")

t = 0
y = 0

while True:
    time.sleep(1.0)
    t += 1
    y += random.normalvariate(0, 1)
    pub_socket.send_pyobj(dict(x=[t], y=[y]))