繁体   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