Bokeh教程:导出和嵌入

目录

本文翻译自 bokeh/bokeh-notebooks 项目,并经过修改。

到目前为止,我们已经看到如何在 Jupyter 中直接内联生成交互式 Bokeh 输出。 也可以在其他上下文中(例如独立 HTML 文件或 Jinja 模板)嵌入交互式 Bokeh 图和布局。 此外,Bokeh 可以将图导出为静态(非交互式)PNG 和 SVG 格式。

我们将在本章中探讨所有这些可能性。 首先,我们进行常规导入。

from bokeh.io import output_notebook, show
output_notebook()

并加载一些将在本章中使用的数据

import pandas as pd

from bokeh.plotting import figure
from bokeh.sampledata.stocks import AAPL

df = pd.DataFrame(AAPL)
df['date'] = pd.to_datetime(df['date'])
df.head()

嵌入交互内容

首先,我们将研究在各种情况下嵌入实时交互 Bokeh 输出的不同方式。

在 Notebook 中显示

正如我们已经看到的,嵌入 Bokeh 输出的第一种方法是在 Jupyter Notebook 中。 提醒一下,下面的单元格将生成一个内联图作为输出,因为我们执行了上面的 output_notebook

p = figure(
    plot_width=800, 
    plot_height=250, 
    x_axis_type="datetime"
)
p.line(
    df['date'], 
    df['close'], 
    color='navy', 
    alpha=0.5
)

show(p)

保存成 HTML 文件

生成包含 Bokeh 内容的独立 HTML 脚本通常也很有用。 这是通过调用 output_file(...) 函数来完成的。 在标准 Python 脚本中执行此操作特别常见,但是这里我们看到也可以在 Notebook 中使用。

from bokeh.io import output_file, show
output_file("plot.html")
# save(p) 将保存而不打开新的浏览器选项卡
show(p)

除了上面的内嵌图外,您还应该看到一个新的浏览器选项卡打开,其中包含新保存的 “plot.html” 文件的内容。 重要的是要注意 output_file 会启动 持续操作模式。 也就是说,所有随后的 show 调用都将生成输出到指定文件。 我们可以通过调用 reset_output 来 “重置” 输出的位置:

from bokeh.io import reset_output
reset_output()

HTML文档中的模板

另一个用例是将 Bokeh 内容嵌入 Jinja HTML 模板中。 我们将首先看一个简单的显式案例,然后看看如何在 Flask 之类的 Web 应用程序框架中使用此技术。

嵌入独立(即不是Bokeh 服务器)内容的最简单方法是使用 components 函数。 这个函数接受一个 Bokeh 对象,并返回一个可以放在任何 HTML 模板中的 <script> 标签和 <div> 标签。 该脚本将执行并将 Bokeh 内容加载到关联的 div 中。

下面的单元格显示了一个完整的示例,包括在 temlpate 中加载 BokehJS JS 和 CSS 资源。

import jinja2
from bokeh.embed import components

# 重要的提示!!模板中加载的 BokehJS 版本应与本地安装的 Bokeh 版本匹配。

template = jinja2.Template("""
<!DOCTYPE html>
<html lang="en-US">

<link
    href="https://cdn.bokeh.org/bokeh/release/bokeh-2.0.0.min.css"
    rel="stylesheet" type="text/css"
>
<script src="https://cdn.bokeh.org/bokeh/release/bokeh-2.0.0.min.js"
        crossorigin="anonymous"></script>

<body>

    <h1>Hello Bokeh!</h1>
    
    <p> Below is a simple plot of stock closing prices </p>
    
    {{ script }}
    
    {{ div }}

</body>

</html>
""")
p = figure(
    plot_width=800, 
    plot_height=250, 
    x_axis_type="datetime"
)
p.line(
    df['date'], 
    df['close'], 
    color='navy', 
    alpha=0.5
)

script, div = components(p)
from IPython.display import HTML
HTML(template.render(
    script=script, 
    div=div
))

请注意,可以将多个对象传递给对 components 的单个调用,以便一次对多个 Bokeh 对象进行模板化。 有关更多信息,请参见 组件用户指南

一旦我们有了来自 components 的脚本和 div,就可以直接在 Web 应用程序中提供包含 Bokeh 内容的渲染页面,例如下面所示的 Flask 应用。

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_bokeh():
   return template.render(
       script=script, 
       div=div
   )
# 取消注释以运行 Flask 服务器。 
# 从 Notebook 菜单栏使用 Kernel -> Interrupt 来停止
app.run(port=5050)

练习

创建自己的模板(或者修改上面的模板)

导出静态图像

有时,需要生成没有任何交互功能的静态绘图图或其他 Bokeh 输出。 Bokeh 支持导出为 PNG 和 SVG 格式。

导出 PNG

Bokeh 支持使用 export_png 函数将绘图或布局导出为 PNG 图像格式。 此函数与一个要导出的 Bokeh 对象和一个将 PNG 输出写入的文件名结合在一起。 传递给 export_png 的 Bokeh 对象通常是一个单一的图像,但不一定如此。 如果导出布局,则整个布局将保存到一个 PNG 图像中。

重要提示: PNG导出功能需要安装一些其他可选的依赖项。获取它们的最简单方法是通过conda:

conda install selenium phantomjs pillow
from bokeh.io import export_png

p = figure(
    plot_width=800, 
    plot_height=250, 
    x_axis_type="datetime"
)
p.line(
    df['date'], df['close'], 
    color='navy', 
    alpha=0.5)

export_png(
    p, 
    filename="plot.png"
)
from IPython.display import Image
Image('plot.png')

练习

将图表布局(例如行或列)另存为 PNG,然后查看会发生什么情况

导出 SVG

Bokeh 还可以在浏览器中生成 SVG 输出,而不是呈现到 HTML canvas。 这是通过在 figure 上设置 output_backend ='svg' 来完成的。 可用于在 output_file HTML 文件或包含 components 的内容中生成 SVG。 也可以和 export_svgs 函数一起使用来保存 .svg 文件。 请注意,为 每个画布 创建了一个 SVG。 无法在 SVG 输出中捕获整个布局或小部件。

重要说明: SVG 输出当前存在一些已知问题,可能不适用于所有用例

from bokeh.io import export_svgs

p = figure(
    plot_width=800, 
    plot_height=250, 
    x_axis_type="datetime", 
    output_backend='svg'
)
p.line(
    df['date'], df['close'], 
    color='navy', 
    alpha=0.5)

export_svgs(
    p, 
    filename="plot.svg"
)

练习

将图表布局(例如行或列)另存为 SVG,然后查看会发生什么情况

参考

https://bokeh.org

https://github.com/bokeh/bokeh-notebooks