[英]Bokeh | Jupyter Notebook | Python | Plot Not Showing
我花了最后幾個星期來學習Bokeh軟件包(對於可視化來說,這是非常好的)。
不幸的是,我遇到了一個我一生無法解決的問題,想出了解決方法。
下面的兩個鏈接很有幫助,但是我似乎無法為我的問題重復。
在Jupyter / Python中使用bokeh繪制交互式餅圖 -請參閱答案#3
https://github.com/bokeh/bokeh/blob/0.12.9/examples/howto/notebook_comms/Jupyter%20Interactors.ipynb
下面的代碼(在Jupyter中)正確顯示了圖形並正確顯示了滑塊,但是我不確定如何連接兩者,因為當我移動滑塊時,圖形保持靜態。
我正在使用Python 3.6和Bokeh 12.9
N = 300
source = ColumnDataSource(data={'x':random(N), 'y':random(N)})
plot = figure(plot_width=950, plot_height=400)
plot.circle(x='x', y='y', source=source)
callback = CustomJS(code="""
if (IPython.notebook.kernel !== undefined) {
var kernel = IPython.notebook.kernel;
cmd = "update_plot(" + cb_obj.value + ")";
kernel.execute(cmd, {}, {})};
""")
slider = Slider(start=100, end=1000, value=N, step=10, callback=callback)
def callback(attr, old, new):
N = slider.value
source.data={'x':random(N), 'y':random(N)}
slider.on_change('value', callback)
layout = column(slider, plot)
curdoc().add_root(layout)
show(widgetbox(slider, width = 300))
show(plot)
在閱讀bokeh文檔並在GitHub上閱讀了視圖線程之后,“回調”功能對我來說還是有點不清楚,因為我不確定要解析什么(實際上,如果attr,old,new也需要解析某些元素)它)
任何幫助將不勝感激
希望我沒有錯過任何顯而易見的事情。
親切的問候,
阿德里安
我想您的問題與服務器有關,盡管您同時具有CustomJS和服務器回調。
我不熟悉在筆記本( push_notebook
)中做bokeh服務器的先前方法。 新的方法是這樣的:將代碼包裝在帶有一個參數(一個文檔)的函數中,並在該文檔上調用add_layout
。 然后,您使用該功能構建一個應用程序並顯示它。
這給出:
from bokeh.models import ColumnDataSource, Slider
from bokeh.layouts import column
from bokeh.plotting import figure, show, output_notebook
from numpy.random import random
from bokeh.application import Application
from bokeh.application.handlers import FunctionHandler
output_notebook()
def modify_doc(doc):
N = 300
source = ColumnDataSource(data={'x':random(N), 'y':random(N)})
plot = figure(plot_width=950, plot_height=400)
plot.circle(x='x', y='y', source=source)
slider = Slider(start=100, end=1000, value=N, step=10)
def callback(attr, old, new):
N = new # but slider.value would also work
source.data={'x': random(N), 'y': random(N)}
slider.on_change('value', callback)
layout = column(slider, plot)
doc.add_root(layout)
app = Application(FunctionHandler(modify_doc))
show(app, notebook_url="localhost:8888")
當前,您正在混合使用不同的交互方式,但是不幸的是,您總是會錯過每種不同方式的東西。
您使用的滑塊來自bokeh,但不幸的是,它看起來類似於slider.on_change
僅在通過bokeh服務器運行時才有效。 從文檔中 :
使用bokeh serve啟動Bokeh服務器,並使用.on_change(或對於某些小部件,.on_click)設置事件處理程序。
我在運行jupyter筆記本和bokeh服務器上找不到太多,但是這個問題似乎在討論這種可能性。 它還提到bokeh.application
,但我從未使用過,所以不知道如何工作的。
您還另外使用了一個自定義js回調,該回調調用jupyter內核並嘗試執行update_plot(value)
,但是您從未定義過此類函數,因此它什么也不做。
然后,您需要一種將數據推送到輸出的方法。 我猜想bokeh服務器可以以某種方式天真地做到這一點,對於沒有bokeh服務器的push_notebook
筆記本, push_notebook
似乎是解決方案。 請注意,您需要show(..., notebook_handle=True)
才能進行推送。
滑條和其他自動部件同步他們的狀態恢復到蟒蛇,所以你可以使用slider.on_change
。 你不需要CustomJS。 數據流應如下所示:
python script -> bokeh server -> html -> userinput -> bokeh server -> python callbacks -> bokeh server updates plots
如果您不想運行單獨的進程,則可以使用jupyter內核在python筆記本中執行代碼。 數據流:
jupyter notebook -> html -> user input -> customjs -> jupyter kernel -> python callbacks -> push_notebook to update plots
output_notebook()
N = 300
source = ColumnDataSource(data={'x':random(N), 'y':random(N)})
plot = figure(plot_width=950, plot_height=400)
plot.circle(x='x', y='y', source=source)
callback = CustomJS(code="""
if (IPython.notebook.kernel !== undefined) {
var kernel = IPython.notebook.kernel;
cmd = "update_plot(" + cb_obj.value + ")";
kernel.execute(cmd, {}, {})};
""")
slider = Slider(start=100, end=1000, value=N, step=10, callback=callback)
# must have the same name as the function that the CustomJS tries to call
def update_plot(N):
source.data={'x':random(N), 'y':random(N)}
# push notebooks to update plots
push_notebook()
layout = column(slider, plot)
# notebook_handle must be true, otherwise push_notebook will not work
h1 = show(layout, notebook_handle=True)
如果您不喜歡bokeh小部件,則可以在jupyter筆記本中使用為交互性而設計的ipywidget。 數據流如下:
jupyter notebook -> html -> user input -> ipywidgets sync automatically -> python callbacks -> push_notebook
我在這里使用interact
但是其他小部件應該可以正常工作。
from ipywidgets import interact
output_notebook()
N = 300
source = ColumnDataSource(data={'x':random(N), 'y':random(N)})
plot = figure(plot_width=950, plot_height=400)
plot.circle(x='x', y='y', source=source)
def update_plot(v):
N = v
print(N)
source.data={'x':random(N), 'y':random(N)}
# push changed plots to the frontend
push_notebook()
# notebook_handle must be true so that push_notebook works
show(plot, notebook_handle=True)
請注意,您需要正確安裝ipywidgets,如果不使用jupyter nbextension enable --py --sys-prefix widgetsnbextension
則需要調用jupyter nbextension enable --py --sys-prefix widgetsnbextension
。 有關詳細信息, 請參閱文檔
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.