使用Python/bokeh在网站中嵌入绘图

Mik*_*ike 13 python bokeh

我试图在个人网站上静态嵌入散景图,并遇到一些我不理解的行为.基本上,我使用散景生成一个情节如下:

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/')
Run Code Online (Sandbox Code Playgroud)

到现在为止还挺好.这会生成一个看起来像的文件(random garbage).embed.js,并打印一个包含html语法的字符串,我手动将其复制到我正在调用的html文件中testembed.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>
Run Code Online (Sandbox Code Playgroud)

如果我有python代码引用我的本地 python安装并将生成的文件(.html和.embed.js)复制到我的本地计算机,我可以在html文件中看到该图.

但是,我真正想做的是在远程计算机上运行,​​并在我的个人网站上通过网络访问html文件.

当我static_path参考我的远程计算机的 python安装时(如上所示,已注释掉),当我通过网络访问它时,我无法在html页面中看到该情节(即访问http://mywebsite.com/ testembed.html).我不知道为什么会这样.

作为参考,这里是定义html片段函数的代码:https: //github.com/ContinuumIO/bokeh/blob/master/bokeh/objects.py#L309 我注意到有一个选项我没有传递create_html_snippet,也就是说, embed_base_url可能与此有关.

提前致谢!麦克风

编辑 我接受了bigreddot建议,解决了这个问题.我遇到的实际问题是,出于安全考虑,我使用的网络服务器只能访问我public_html目录中的内容.解决方法是进入我rsyncbokeh/static目录public_html并指向:

rsync -ax /opt/anaconda/lib/python2.7/site-packages/bokeh/server/static/ /home/myusername/public_html/bokeh-static/
Run Code Online (Sandbox Code Playgroud)

然后修改我的代码如下:

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')
Run Code Online (Sandbox Code Playgroud)

然后显然将生成的html复制到testembed.html.

big*_*dot 12

更新:create_html_snippet原始问题中提到的功能在几年前已被弃用和删除.现在有各种更新的方法可以在bokeh.embed模块中嵌入Bokeh内容.这个答案将总结其中一些.

独立内容

独立Bokeh内容是纯HTML/JS/CSS,不受正在运行的Bokeh服务器的支持.但是,独立的Bokeh内容仍然可以高度交互,使用绘图工具(例如平移,缩放,选择),链接刷子和触发CustomJS操作的小部件.有几种方法可以嵌入独立内容:

json_item

如果您想创建可以由JS函数加载的内容的纯JSON表示,则可以使用该json_item函数.例如,您可以从Flask端点服务JSON:

@app.route('/plot')
def plot():
    p = make_plot('petal_width', 'petal_length')
    return json.dumps(json_item(p, "myplot"))
Run Code Online (Sandbox Code Playgroud)

然后页面可以使用JavaScript代码加载和呈现内容,如下所示:

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

<script>
fetch('/plot')
    .then(function(response) { return response.json(); })
    .then(function(item) { Bokeh.embed.embed_item(item); })
</script>
Run Code Online (Sandbox Code Playgroud)

这是假设你已经加载了页面上的BokehJS库,例如,通过模板CDN.render()<head>页面.请在此处查看完整的最小示例.

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)
Run Code Online (Sandbox Code Playgroud)

返回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>
Run Code Online (Sandbox Code Playgroud)

如上所述,您需要对页眉中的BokehJS JS和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")
Run Code Online (Sandbox Code Playgroud)

这会生成一个可以保存或提供的基本页面等.如果需要,您还可以提供自己的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")
Run Code Online (Sandbox Code Playgroud)

返回的内容script可以在HTML页面的任何位置进行模板化,Bokeh应用程序将出现在那里.还有许多其他可能性,例如单独嵌入应用程序组件,为用户自定义会话或在代理/负载平衡器后面运行.Bokeh服务器可能还需要配置为允许访问嵌入页面.有关完整详细信息,请参阅"用户指南"中的" 运行散热服务器"一章.

另一种可能更简单的"嵌入"Bokeh服务器应用程序的方法是使用指向正在运行的Bokeh应用程序的公共URL的IFrame.