2017-10-03 22 views
1

私はここ数週間、Bokehパッケージを学習しました(私の見解では、視覚的には優れています)。|ジュピターノート| Python |プロットが表示されない

残念ながら、私は私の人生では解決できない問題を抱えています。

以下の2つのリンクが参考になっていますが、私の問題では複製できないようです。

Using bokeh to plot interactive pie chart in Jupyter/Python - (Jupyterで)以下のコードは正しくグラフが表示され、正しくスライダーが表示されますが、私は2つのときに私のように接続する方法がわからないよ#3

https://github.com/bokeh/bokeh/blob/0.12.9/examples/howto/notebook_comms/Jupyter%20Interactors.ipynb

に答えることを参照してください。スライダーを動かすと、グラフは静止したままです。私は完全にわからないよう

私はボケのマニュアルを読み、GitHubの上のビューのスレッドを読んだ後はPython 3.6とボケ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) 

を使用していますが、「コールバック」関数は、私にとっては少し不明確です何(新古事実attrの、であまりにも解析された特定の要素が必要な場合)、それを解析する

すべてのヘルプは非常にうまくいけば

をいただければ幸い、私は紛れも明らかに何かを見逃していません。

種類よろしく、

エイドリアン

+0

あなたは[this](https://bokeh.pydata.org/en/latest/docs/user_guide/notebook.html#jupyter-interactors)ガイドを見ましたか?あなたは重要な 'push_notebook'を見逃しています。 – syntonym

+0

返信いただきありがとうございます!私はJupyter内でこのコードを実行しており、完全に動作します。しかし、私のコードにpush_notebookを追加しても何も変わりません。あなたのマシンでこれを実行しましたか? – AdrianC

+0

私は 'show'関数に' notebook_handle = True'も必要と思います。現在、私はあなたのコードを実行することはできませんが、誰もあなたを助けることができなければ、私は今晩見ていきます。たぶんあなたがもっと早くあなたを助けるかもしれない例を実行している輸入などを追加する場合。カスタムjsコールバックをやっている理由は分かりません。おそらくウェッジの例からですか?私は 'plot.circle'ではそれは必要ないと思っていますが、私は今晩しかテストできません。 – syntonym

答えて

3

は、現在の対話のためのさまざまな方法を混合しているが、残念ながら、あなたは常にそれぞれの異なる方法のために何かを欠場します。

使用するスライダーはbokehからのものですが、残念ながらslider.on_changeはbokehサーバーを使用している場合のみ動作します。 documentationから:

使用ボケは、ボケサーバを起動し、.on_change(またはいくつかのウィジェットのために、.on_click)にイベントハンドラを設定するのに役立ちます。

私は実際にはjupyter notebookとbokeh serverを走らせることがそれほどできませんでしたが、this issueはその可能性を議論しているようです。それはまた、bokeh.applicationを言及しますが、私はそれを使用したことがないので、どのように動作するのか分かりません。

また、jupyterカーネルを呼び出してupdate_plot(value)を実行しようとするカスタムjsコールバックを使用しますが、このような関数は決して定義されないため、何もしません。

次に、データを出力にプッシュする方法が必要です。私はbokehサーバが何とかそのようなことをすることができると思います。bokehサーバなしのjupyterノートにはpush_notebookが解決策と思われます。プッシュするにはshow(..., notebook_handle=True)が必要です。

ソリューション1つの利用ボケサーバー

スライダーや他の人はあなたがslider.on_changeを使用できるように自動的に、バックのpythonに自分の状態を同期ウィジェット。 CustomJSは必要ありません。あなたがでコードを実行するjupyterカーネルを使用することができます別々のプロセスを実行したくない場合は

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

ソリューション2使用のボケスライダーが、同期がCustomJS

経由:データの流れは以下のようになりますあなたの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あなたはjupyterノートブックでの対話のために設計されているipywidgetsを使用することができボケのウィジェットに結婚していない場合

。私はここにinteract使用しますが、期待通りに、他のウィジェットが動作するはず

jupyter notebook -> html -> user input -> ipywidgets sync automatically -> python callbacks -> push_notebook

:データフローは以下の通りです。あなたがcondaを使用していない場合jupyter nbextension enable --py --sys-prefix widgetsnbextensionを呼び出すinlcudesあなたが適切ipywidgetsをインストールする必要が

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) 

注意、。詳細はsee the documentation

+0

ソリューション2は完全に機能します。私を助けてくれてありがとう、徹底的な説明をしてくれてありがとあなたの非常に親切。私自身の知識はもっとありますが、ソリューション1はソリューション2よりも賛否両論を持っていますか(またはその逆)?私はこの答えが主観的であり、個人的な意見やベストプラクティスの方法を分かち合うことができれば、達成したいことに依存していると思います。質問をする前にソリューション3を試しましたが、Bokeh Dashboardsのビルドを開始する場合、それほど柔軟性がないと感じました。 – AdrianC

+0

CustomJSコースはipythonがある場合にのみ動作しますので、「純粋なWebアプリケーション」bokehサーバーに移動したい場合は、おそらく行く方法です。私はbokehサーバーを試したことはありませんが、本当にそれがalexの答えのように単純であれば、私は確かにそれを試してみるでしょう。本当にあなたがしたいことにかかっています。 – syntonym

2

私はあなたがCustomJSとサーバーのコールバックの両方を持っているが、あなたの質問には、サーバに関連すると仮定します。

私はノートブック(push_notebook)のbokehサーバーを実行する以前の方法に慣れていません。 新しい方法は次のようになります:1つのパラメータ(ドキュメント)を取得し、そのドキュメントに対して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") 
+0

私はボケでその新しい方法について多くの情報を見つけることができませんでした。これは既にユーザーガイドに文書化されているのですか、それともAPIのドキュメントにのみ記載されていますか?これはまた、ジュピターのノートブックやボケサーバーでのみ動作しますか? – syntonym

+0

この例はノートブックで動作し、基本的に 'app'を提供するサーバプロセス(またはスレッドではない)を起動します。 私が知る限り、これは完全には文書化されていません(特にユーザーガイド) – Alex

+0

訂正:実際には[ここ](https://bokeh.pydata.org/en/latest/docs/user_guide/ server.html#embedding-bokeh-server-as-a-library)を[例](https://github.com/bokeh/bokeh/tree/0.12.9/examples/howto/server_embed/notebook_embed)に置き換えてください。ipynb) – Alex

関連する問題