我正在尝试使用 Bokeh 在 Jupyter notebook 中绘制流式数据集.这是我目前所拥有的。
在命令行中,我通过运行命令启动 Bokeh 服务器
$> bokeh server
这是我的 Jupyter notebook 中的代码
import numpy as np
from IPython.display import clear_output
# ------------------- new cell ---------------------#
from bokeh.models.sources import ColumnDataSource
from bokeh.client import push_session
from bokeh.driving import linear
from bokeh.plotting import figure
from bokeh.io import curdoc, output_notebook, show
# ------------------- new cell ---------------------#
output_notebook()
# ------------------- new cell ---------------------#
my_figure = figure(plot_width=800, plot_height=400)
test_data = ColumnDataSource(data=dict(x=[0], y=[0]))
linea = my_figure.line("x", "y", source=test_data)
# ------------------- new cell ---------------------#
new_data=dict(x=[0], y=[0])
x = []
y = []
step_size = 0.1 # increment for increasing step
@linear(m=step_size, b=0)
def update(step):
x.append(step)
y.append(np.random.rand())
new_data['x'] = x
new_data['y'] = y
test_data.stream(new_data, 10)
clear_output()
show(my_figure)
if step > 10:
session.close()
# ------------------- new cell ---------------------#
# open a session to keep our local document in sync with server
session = push_session(curdoc())
period = 100 # in ms
curdoc().add_periodic_callback(update, period)
session.show() # open a new browser tab with the updating plot
session.loop_until_closed()
目前,我得到的结果是 Jupyter notebook 中的闪烁图,以及新浏览器选项卡中的更新图。我想要以下任何一个
- Jupyter 中的一个很好的更新图,没有闪烁
- 只是新浏览器标签中的剧情
我尝试删除 show(my_figure)
但每次更新都会打开一个新选项卡。我还尝试将刷新率降低到 10 毫秒,period = 10
; session.show()
效果很好,但笔记本最终崩溃了,因为它无法快速刷新。
如何在 Jupyter 中获得良好的 Bokeh 图刷新率?或者我如何关闭 Jupyter plot 而只有一个选项卡显示更新的 plot?
最佳答案
这是修改笔记本的代码,遵循@bigreddot 的评论,它使用 push_notebook
在笔记本中产生更清晰的结果(它不需要您运行 bokeh serve
用于绘图)。它不使用回调;我不确定这是否是一个优势。事实上,如果您希望在新数据点出现时更新绘图,您可以在 while
循环的开头添加一个 if data_event:
语句,然后调整 sleep 时间根据事件发生率工作得很好。
This page官方文档中的内容提供了有关在 Jupyter 笔记本中使用 Bokeh 的更多有用信息。
import time
import numpy as np
# ------------------- new cell ---------------------#
from bokeh.models.sources import ColumnDataSource
from bokeh.plotting import figure
from bokeh.io import output_notebook, show, push_notebook
# ------------------- new cell ---------------------#
output_notebook()
# ------------------- new cell ---------------------#
my_figure = figure(plot_width=800, plot_height=400)
test_data = ColumnDataSource(data=dict(x=[0], y=[0]))
line = my_figure.line("x", "y", source=test_data)
handle = show(my_figure, notebook_handle=True)
new_data=dict(x=[0], y=[0])
x = []
y = []
step = 0
step_size = 0.1 # increment for increasing step
max_step = 10 # arbitrary stop point for example
period = .1 # in seconds (simulate waiting for new data)
n_show = 10 # number of points to keep and show
while step < max_step:
x.append(step)
y.append(np.random.rand())
new_data['x'] = x = x[-n_show:] # prevent filling ram
new_data['y'] = y = y[-n_show:] # prevent filling ram
test_data.stream(new_data, n_show)
push_notebook(handle=handle)
step += step_size
time.sleep(period)
请注意添加了 new_data['x'] = x = x[-n_show]
(对于 y
也是如此)所以理论上这可以无限期地运行而不会填充您的内存。此外,实际上流式传输某种数据源(可能来自网络)以使其成为更现实的示例会很好。最后,您可能意识到了这一点,但是在您使用流图运行单元之后,内核将被锁定,直到它完成或被中断;您不能执行其他单元格/代码。如果您想要分析/控制功能,它们应该放在 while
循环中。
关于python - 如何以高刷新率将数据流式传输到 Jupyter 中的 Bokeh 图?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43101497/