[英]How do stream data to a Bokeh plot in Jupyter with a high refresh rate?
我正在嘗試使用Bokeh在Jupyter筆記本中繪制流數據集。 這是我到目前為止所擁有的。
從命令行我通過運行命令啟動散景服務器
$> bokeh server
這是我的Jupyter筆記本的代碼
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筆記本中的閃爍情節,以及新瀏覽器選項卡中的一個很好的更新圖。 我想要以下任何一種
我嘗試刪除show(my_figure)
但每次更新都打開了一個新選項卡。 我也嘗試將刷新率降低到10毫秒, period = 10
; session.show()
運行良好,但筆記本最終崩潰,因為它無法快速刷新。
如何在Jupyter中獲得散景圖的良好刷新率? 或者我如何關閉Jupyter圖並且只有一個選項卡顯示更新圖?
這是修改后的筆記本的代碼,遵循@ bigreddot的評論,它使用push_notebook
在筆記本中產生更清晰的結果(它不需要你為繪圖運行bokeh serve
)。 它不使用回調; 我不確定這是否有利。 因此,如果您希望在新數據點進入時更新繪圖,則可以在while
循環開始時添加if data_event:
語句,然后根據事件速率調整睡眠時間。
官方文檔中的此頁面提供了有關在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
循環。
@Steven C. Howell
受您的示例啟發,我使用非阻塞回調函數對其進行了修改。 它沒有使用add_periodic_callback,因為此功能在jupyter筆記本中不起作用( 在Bokeh文檔中提到 )。 但是,在使用jupyter筆記本時,能夠執行非阻塞數據流可能很有用。
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 cell ---------------------#
from threading import Thread
stop_threads = False
def blocking_callback(id, stop):
new_data=dict(x=[0], y=[0])
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 True:
new_data['x'] = [step]
new_data['y'] = [np.random.rand()]
test_data.stream(new_data, n_show)
push_notebook(handle=handle)
step += step_size
time.sleep(period)
if stop():
print("exit")
break
thread = Thread(target=blocking_callback, args=(id, lambda: stop_threads))
thread.start()
這樣做的好處是,無限數據流不會阻止后續單元執行:
# ------------------- new cell ---------------------#
# preceding streaming is not blocking
for cnt in range(10):
print("Do this, while plot is still streaming", cnt)
# ------------------- new cell ---------------------#
# you might also want to stop the thread
stop_threads=True
del thread
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.