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()
![](https://cdn.perillaroc.wang/image/blog/2020/bokeh/exporting/stocks-df-head.png)
嵌入交互内容
首先,我们将研究在各种情况下嵌入实时交互 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)
![](https://cdn.perillaroc.wang/image/blog/2020/bokeh/exporting/notebook.png)
保存成 HTML 文件
生成包含 Bokeh 内容的独立 HTML 脚本通常也很有用。
这是通过调用 output_file(...)
函数来完成的。
在标准 Python 脚本中执行此操作特别常见,但是这里我们看到也可以在 Notebook 中使用。
from bokeh.io import output_file, show
output_file("plot.html")
# save(p) 将保存而不打开新的浏览器选项卡
show(p)
![](https://cdn.perillaroc.wang/image/blog/2020/bokeh/exporting/html.png)
除了上面的内嵌图外,您还应该看到一个新的浏览器选项卡打开,其中包含新保存的 “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
))
![](https://cdn.perillaroc.wang/image/blog/2020/bokeh/exporting/jinjia.png)
请注意,可以将多个对象传递给对 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')
![](https://cdn.perillaroc.wang/image/blog/2020/bokeh/exporting/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,然后查看会发生什么情况