web-dev-qa-db-ja.com

Python / bokehを使用してWebサイトにプロットを埋め込む

個人のWebサイトにボケプロットを静的に埋め込もうとしていますが、理解できない動作が発生しています。基本的に、私は次のようにボケを使用してプロットを生成しています。

import bokeh.plotting as bplt
import numpy as np

x=np.random.random(100)
y=np.random.random(100)

bplt.output_file("t.html")
plot=bplt.line(x,y)

##the following line refers to the bokeh installed on my home computer
print plot.create_html_snippet(
           static_path='/usr/local/lib/python2.7/site-packages/bokeh/server/static/')

##the following line refers to the bokeh installed on my remote computer
#print plot.create_html_snippet(
#           static_path='/opt/anaconda/lib/python2.7/site-packages/bokeh/server/static/')

ここまでは順調ですね。これにより、(random garbage).embed.jsのようなファイルが生成され、testembed.htmlと呼んでいるhtmlファイルに手動でコピーしたhtml構文を含む文字列が出力されます。これを以下に再現します。

<html>
<body>

<h2>Simple Embed Example</h2>
<p>This is where my plot should be:</p>
<p>
<!--The next 4 lines are the output of the print statement from the python code-->
<script src="ccbd451a-6995-4dd2-b99c-e4140b362997.embed.js"
        bokeh_plottype="embeddata"
        bokeh_modelid="ccbd451a-6995-4dd2-b99c-e4140b362997"
        bokeh_modeltype="Plot" async="true"></script>
</p>

</body>
</html>

pythonコードリファレンスがある場合は、 local pythonインストールして、生成されたファイル(.htmlおよび。 embed.js)をローカルコンピューターに送信すると、htmlファイルのプロットを見ることができます

しかし、私が本当にやりたいのは、これをリモートコンピューターで実行し、個人用サイトのWebからhtmlファイルにアクセスできるようにすることです。

static_pathリモートコンピュータの pythonインストール(上記のようにコメントアウト)を参照している場合、私Web経由でアクセスすると(つまり、 http://mywebsite.com/testembed.html)にアクセスすると、htmlページにプロットが表示されません。 )。なぜこれが起こっているのかわかりません。

参考までに、htmlスニペット関数が定義されているコードは次のとおりです。 https://github.com/ContinuumIO/bokeh/blob/master/bokeh/objects.py#L309 オプション私は not create_html_snippet、つまりembed_base_urlを渡しますが、これは可能性がありますこの。

前もって感謝します!マイク

[〜#〜] edit [〜#〜]bigreddotのアドバイスを受けて、問題を解決しました。私が抱えていた実際の問題は、私が使用していたWebサーバーが、セキュリティ上の理由から、私のpublic_htmlディレクトリ内のものにしかアクセスできないことでした。回避策は、rsyncbokeh/staticディレクトリを私のpublic_htmlに入れ、それを指すことでした。

rsync -ax /opt/anaconda/lib/python2.7/site-packages/bokeh/server/static/ /home/myusername/public_html/bokeh-static/

次に、コードを次のように変更します。

import bokeh.plotting as bplt
import numpy as np

x=np.random.random(100)
y=np.random.random(100)

bplt.output_file("t.html")
plot=bplt.line(x,y)


#the following line refers to the bokeh rsynced to my directory
print plot.create_html_snippet(
           static_path='http://www.my_server_website/~myusername/bokeh-static/', 
           embed_base_url = 'http://www.my_server_website/~myusername/where_.js_file_is_located')

そして明らかに生成されたhtmlをtestembed.htmlにコピーします。

14
Mike

更新:元の質問で言及された_create_html_snippet_関数は非推奨になり、数年前に削除されました。 _bokeh.embed_ モジュールで利用可能なBokehコンテンツを埋め込むためのさまざまな新しい方法があります。この回答はそれらのいくつかを要約します。

スタンドアロンコンテンツ

スタンドアロンのBokehコンテンツは、実行中のBokehサーバーによってサポートされていない純粋なHTML/JS/CSSです。ただし、スタンドアロンのBokehコンテンツは、プロットツール(パン、ズーム、選択など)、リンクされたブラッシング、CustomJSアクションをトリガーするウィジェットを使用して、高度にインタラクティブにすることができます。スタンドアロンコンテンツを埋め込む方法はいくつかあります。

_json_item_

JS関数でロードできるコンテンツの純粋JSON表現を作成する場合は、 _json_item_ 関数を使用できます。例として、Flaskエンドポイント:

_@app.route('/plot')
def plot():
    p = make_plot('petal_width', 'petal_length')
    return json.dumps(json_item(p, "myplot"))
_

次に、ページは次のようなJavaScriptコードを使用してコンテンツをロードおよびレンダリングできます。

_<div id="myplot"></div>

<script>
fetch('/plot')
    .then(function(response) { return response.json(); })
    .then(function(item) { Bokeh.embed.embed_item(item); })
</script>
_

これは、ページにBokehJSライブラリをロードしたことを前提としています。ページの_<head>_でCDN.render()をテンプレート化する。 ここに完全な最小限の例 を参照してください。

components

ページにテンプレート化できる単純な_<script>_タグと_<div>_を生成する場合は、 components 関数を使用できます。

_from bokeh.plotting import figure
from bokeh.embed import components

plot = figure()
plot.circle([1,2], [3,4])

script, div = components(plot)
_

返されたscriptdiv(または複数のアイテムを渡す場合はdiv)をページに挿入できます。

_<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>Bokeh Scatter Plots</title>

        <!-- COPY/PASTE BOKEHJS RESOURCES HERE -->

        <!-- COPY/PASTE SCRIPT HERE -->

    </head>
    <body>
        <!-- INSERT DIVS HERE -->
    </body>
</html>
_

上記のように、ページヘッドでBokehJSJSおよびCSSリソースをハードコーディングまたはテンプレート化する必要があります。 CDN.render()

_file_html_

完全なHTMLページ全体(つまり、_<head></head><body></body>_を含む)を生成する場合は、 _file_html_ 関数を使用できます。

_from bokeh.plotting import figure
from bokeh.resources import CDN
from bokeh.embed import file_html

plot = figure()
plot.circle([1,2], [3,4])

html = file_html(plot, CDN, "my plot")
_

これにより、保存や提供などが可能な基本的なページが生成されます。必要に応じて、独自のJinjaテンプレートを提供することもできます(詳細については、ドキュメントを参照してください)。

Bokehサーバーアプリケーション

Bokehサーバーアプリケーションは、Bokehプロットとウィジェットをライブ実行中のPythonプロセスに接続できるため、UIインタラクション、選択、ウィジェット操作などのイベントで実際のPython =コード(例:Pandasまたはscikit-learn)。

基本的なBokehアプリケーションをページテンプレートに埋め込むための最も一般的な方法は、_server_document_を使用することです。

_from bokeh.embed import server_document
script = server_document("https://demo.bokeh.org/slider")
_

返されたscriptは、HTMLページのどこにでもテンプレート化でき、Bokehアプリケーションがそこに表示されます。他にも多くの可能性があります。アプリコンポーネントを個別に埋め込んだり、ユーザー向けにセッションをカスタマイズしたり、プロキシ/ロードバランサーの背後で実行したりします。埋め込みページへのアクセスを許可するようにBokehサーバーを構成する必要がある場合もあります。詳細については、ユーザーガイドの Bokehサーバーの実行 の章を参照してください。

Bokehサーバーアプリケーションを「埋め込む」ためのもう1つの、おそらくより簡単な方法は、実行中のBokehアプリのパブリックURLを指すIFrameを使用することです。

16
bigreddot

編集:この回答の情報は、非常に古いバージョンのBokehに関連しており、使用法には関係ありません


embed_base_urlは、JavaScriptが埋め込みファイルを検索するURLパス(絶対パスまたは相対パス)を制御します。

embed_save_locは、pythonが埋め込みファイルを書き出すディレクトリを制御します。server= Trueの場合、embed_save_locは必要ありません。

static_pathは、javascriptがbokeh.jsおよびbokeh.cssのURLを構築するために使用するURLパス(絶対パスまたは相対パス)を制御します。デフォルトはhttp://localhost:5006/static/ですが、CDNを簡単に指すこともできます。

ボケサーバーを実行しているときは、http://localhost:5006/bokeh/generate_embed/staticに移動します。バグがあるため、マスターで実行する必要があると思います。

編集:CDNは「コンテンツ配信ネットワーク」であり、ファイルサーバーの単なる空想用語です。たとえば、bokeh.jsを http://cdn.bokeh.org/bokeh-0.4.2.js (または http://cdn.bokeh.org/bokeh)でホストします-0.4.2.min.js )誰でも使用できます。

3
paddy