使用Python/bokeh将情节嵌入网站中 [英] Embedding a plot in a website with Python/bokeh

查看:113
本文介绍了使用Python/bokeh将情节嵌入网站中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图将散景图静态地嵌入到个人网站中,并且遇到一些我不理解的行为.基本上,我使用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/')

到目前为止,一切都很好.这将产生一个看起来像(random garbage).embed.js的文件,并包含一个包含html语法的打印字符串,该字符串已被我手动复制到我正在调用的testembed.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安装程序(如上所示,已注释掉)时,我在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的建议,从而解决了该问题.我遇到的实际问题是,出于安全目的,我正在使用的Web服务器只能访问public_html目录中的内容.解决方法是将rsync bokeh/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.

解决方案

更新:最初问题中提到的create_html_snippet函数在多年前已被弃用并删除.现在,在 bokeh.embed 模块.这个答案将总结其中的一些.

独立内容

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

json_item

如果您想创建可以由JS函数加载的内容的纯JSON表示形式,则可以使用

然后页面可以使用如下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>可以模板化到页面中,则可以使用

如上所述,您将需要在页眉中对BokehJS JS和CSS资源进行硬编码或模板化,例如与CDN.render()

file_html

如果要生成整个完整的HTML页面(即包括<head></head><body></body>),则可以使用

这将生成一个可以保存或提供服务的基本页面.如果需要,您还可以提供自己的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应用程序的公共URL的IFrame.

I am trying to statically embed a bokeh plot in a personal website, and am encountering some behavior I do not understand. Basically, I am generating a plot using bokeh as follows:

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/')

So far so good. This produces a file that looks like (random garbage).embed.js, and a prints string containing html syntax that I manually copy into an html file I am calling testembed.html, which I have reproduced below:

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

If I have the python code reference my local python installation and copy the generated files (.html and .embed.js) to my local computer, I can see the plot in the html file.

However, what I really want to do is have this run on a remote computer, and have the html file accessible through the web on my personal site.

When I have static_path refer to my remote computer's python install (as shown above, commented out), I can't see the plot in the html page when I access it through the web (ie, going to http://mywebsite.com/testembed.html). I have no idea why this is happening.

For reference, here is the code where the html snippet function is defined: https://github.com/ContinuumIO/bokeh/blob/master/bokeh/objects.py#L309 and I note there is an option I am not passing in create_html_snippet, ie, embed_base_url, which could have something to do with this.

Thanks in advance! Mike

EDIT I took bigreddot's advice, which solved the problem. The actual problem I had been having was that the webserver I was using was, for security purposes, only able to access things in my public_html directory. The workaround was to rsync the bokeh/static directory into my public_html and point to that:

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

and then modify my code as follows:

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')

and then obviously copy the generated html into the testembed.html.

解决方案

UPDATE: the create_html_snippet function mentioned in the original question was deprecated and removed years ago. There are now various newer ways to embed Bokeh content available in the bokeh.embed module. This answer will summarize some of them.

Standalone Content

Standalone Bokeh content is pure HTML/JS/CSS that is not backed by a running Bokeh server. However, standalone Bokeh content can still be highly interactive, with plot tools (e.g. pan, zoom, selection), linked brushing, and widgets that trigger CustomJS actions. There are several ways to embed standalone content:

json_item

If you would like to create a pure JSON representation of the content that can be loaded by JS functions, you can use the json_item function. As an example, you might server the JSON from a Flask endpoint:

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

Then the page can load and render the content with JavaScript code like this:

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

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

This assumes you have loaded the BokehJS library on the page, e.g. by templating CDN.render() in the <head> of the page. See a complete minimal example here.

components

If you would like to generate a simple <script> tag and <div> that can be templated into a page to, you can use the components function:

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

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

script, div = components(plot)

The returned script and div (or divs it you pass multiple items) can be inserted in to page:

<!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>

As above, you will need to hardcode or template the BokehJS JS and CSS resources in the page head, e.g. with CDN.render()

file_html

If you want to generate entire complete HTML pages (i.e. including <head></head><body></body>), you can use the file_html function:

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")

This generates a basic page that can be saved or served, etc. If desired you can also supply your own Jinja template (see docs for details).

Bokeh Server Applications

Bokeh server applications can connect Bokeh plots and widgets to a live running Python process, so that events like UI interactions, making selections, or widget manipulations can trigger real Python code (e.g. Pandas or scikit-learn).

To embed a basic Bokeh application in a page template, the most common method is to use server_document:

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

The returned script can be templated anywhere in an HTML page, and the Bokeh application will appear there. There are many other possibilities, e.g. embedding app components individually, customizing sessions for users, or running behind proxies/load balancers. The Bokeh server may also need to be configured to allow access to the embedding page. For full details see the Running a Bokeh Server chapter of the Users Guide.

Another, possibly simpler way to "embed" a Bokeh server application, is to use IFrames pointing at the public URL of a running Bokeh app.

这篇关于使用Python/bokeh将情节嵌入网站中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆