簡體   English   中英

散景| Jupyter筆記本| Python | 情節未顯示

[英]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)才能進行推送。

解決方案1使用背景虛化服務器

滑條和其他自動部件同步他們的狀態恢復到蟒蛇,所以你可以使用slider.on_change 你不需要CustomJS。 數據流應如下所示:

python script -> bokeh server -> html -> userinput -> bokeh server -> python callbacks -> bokeh server updates plots

解決方案2使用bokeh滑塊,但通過CustomJS同步

如果您不想運行單獨的進程,則可以使用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)

解決方案3使用ipywidgets

如果您不喜歡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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM