【问题标题】:Embedding a plot in a website with Python/bokeh使用 Python/bokeh 在网站中嵌入绘图
【发布时间】:2014-04-16 05:12:58
【问题描述】:

我正在尝试在个人网站中静态嵌入散景图,但遇到了一些我不理解的行为。基本上,我正在使用散景生成一个情节,如下所示:

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 代码引用我的 本地 python 安装并将生成的文件(.html 和 .embed.js)复制到我的本地计算机,我 可以看到 html 文件中的绘图。

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

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

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

提前致谢! 迈克

编辑 我接受了bigreddot 的建议,解决了这个问题。我遇到的实际问题是,出于安全目的,我使用的网络服务器只能访问我的 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中。

【问题讨论】:

    标签: python bokeh


    【解决方案1】:

    编辑:此答案中的信息与 非常 旧版本的 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 。我认为这需要您在 master 上运行,因为存在错误。

    编辑:CDN 是“内容交付网络”,它只是文件服务器的一个花哨术语。例如,我们将 bokeh.js 托管在 http://cdn.bokeh.org/bokeh-0.4.2.js(或 http://cdn.bokeh.org/bokeh-0.4.2.min.js)供任何人使用。

    【讨论】:

    • 在下面查看我对@bigreddot 的评论,但我也不完全了解服务器的相关性;据我了解,我没有运行服务器......只是试图静态嵌入 javascript。还有什么是CDN?
    【解决方案2】:

    更新:原始问题中提到的 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"))
    

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

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

    这假设您已经在页面上加载了 BokehJS 库,例如通过在页面的&lt;head&gt; 中模板化CDN.render()。见complete minimal example here

    components

    如果你想生成一个简单的&lt;script&gt;标签和&lt;div&gt;,可以模板化到一个页面中,你可以使用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>
    

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

    file_html

    如果要生成整个完整的 HTML 页面(即包括&lt;head&gt;&lt;/head&gt;&lt;body&gt;&lt;/body&gt;),可以使用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 绘图和小部件连接到实时运行的 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 服务器可能还需要配置为允许访问嵌入页面。有关详细信息,请参阅用户指南的 Running a Bokeh Server 章节。

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

    【讨论】:

      猜你喜欢
      • 2016-07-13
      • 2020-08-24
      • 2015-10-15
      • 1970-01-01
      • 1970-01-01
      • 2017-10-01
      • 1970-01-01
      • 2012-08-09
      • 2019-05-09
      相关资源
      最近更新 更多