Jupyter#

在 Notebook 中工作#

Jupyter Notebook 是可计算的文档,常用于探索性工作、数据分析、教学和演示。Notebook 是一系列输入单元格,可以单独执行以立即显示其输出。除了经典 Notebook,还有用于较新的 JupyterLab 项目的 Notebook。Bokeh 可以嵌入独立的和 Bokeh 服务器内容,两者都可以。

独立输出#

独立的 Bokeh 内容不需要 Bokeh 服务器,可以直接嵌入到经典的 Jupyter Notebook 以及 JupyterLab 中。

经典 Notebook#

要在经典的 Jupyter Notebook 中内联显示 Bokeh 绘图,请使用 output_notebook() 函数,来自 bokeh.io,而不是(或除了)output_file() 函数。不需要其他修改。当您调用 show() 时,绘图将内联显示在下一个 Notebook 输出单元格中。请参阅下面的 Jupyter 屏幕截图

Screenshot of a Jupyter notebook displaying a Bokeh scatterplot inline after calling show().

要让单个 Notebook 输出单元格显示多个绘图,请在输入单元格中多次调用 show()。绘图将按顺序显示。

Screenshot of a Jupyter notebook displaying multiple Bokeh scatterplots inline after calling show() multiple times.

JupyterLab#

要将 JupyterLab 与 Bokeh 一起使用,您至少应使用 JupyterLab 3.0 版本。在 JupyterLab 中启用 Bokeh 可视化还需要安装 jupyter_bokeh 扩展。

安装 JupyterLab 后,您可以使用 pipconda 来安装 jupyter_bokeh

使用 conda 安装

确保您已安装 AnacondaMiniconda。使用以下命令安装 jupyter_bokeh

conda install jupyter_bokeh

使用 pip 安装

使用以下命令安装 jupyter_bokeh

pip install jupyter_bokeh

有关在低于 3.0 版本的 JupyterLab 中安装 jupyter_bokeh 的说明,请参阅 README,位于 jupyter_bokeh 的 GitHub 仓库中。

安装 jupyter_bokeh 后,您可以像使用 经典 Notebook 一样使用 Bokeh。

Screenshot of Jupyterlab with a Bokeh ridgeplot displayed inline.

Bokeh 服务器应用程序#

您还可以嵌入完整的 Bokeh 服务器应用程序,将绘图事件和 Bokeh 的内置小部件直接连接到 Python 回调代码。有关 Bokeh 服务器应用程序的常规信息,请参阅 Bokeh 服务器。有关嵌入在 Jupyter Notebook 中的 Bokeh 应用程序的完整示例,请参阅以下 Notebook

JupyterHub#

从您自己的 JupyterHub 实例运行 Notebook 时,需要执行一些额外的步骤来嵌入 Bokeh 服务器应用程序,并启用客户端浏览器和在 JupyterLab 单元格中运行的 Bokeh 服务器之间的网络连接。这是因为您的浏览器需要连接到 Bokeh 服务器正在监听的端口。但是,JupyterHub 充当您的浏览器和您的 JupyterLab 容器之间的反向代理。

Bokeh 通过提供 notebook_url 参数来解决此问题,该参数可以传递一个可调用对象,以基于整数端口计算最终 URL。此外,如果 JupyterHub 管理员定义了环境变量 JUPYTER_BOKEH_EXTERNAL_URL,则定义 notebook_url 的过程将变为完全自动化,并且不再需要指定 notebook_url。这样做的好处是,同一个 Notebook 可以在 JupyterHub 和独立的 JupyterLab 会话中未经修改地运行。

所需依赖项#

按照上面所有的 JupyterLab(而非 JupyterHub)说明进行操作,然后继续安装 jupyter-server-proxy 包,并按如下方式启用服务器扩展

pip install jupyter-server-proxy && jupyter server extension enable --py jupyter-server-proxy

如果您打算使用 JupyterLab,则需要安装相应的扩展,可以从 GUI 安装,也可以使用以下命令安装

jupyter labextension install @jupyterlab/server-proxy

JupyterHub 管理员指南#

如果您是 JupyterHub 管理员,您可以通过在 Notebook 环境中设置环境变量,使 Bokeh 自动与未更改的 Notebook 一起工作

export JUPYTER_BOKEH_EXTERNAL_URL="https//our-hub.science.edu"

通常,这在 JupyterHub Helm chart 配置 YAML 中完成,如下所示

hub:
  single_user:
    extraEnv:
      JUPYTER_BOKEH_EXTERNAL_URL="https://our-public-hub-name.edu"

上述操作的最终效果是,bokeh 自动使用下一节的技术,并且不需要额外的操作。

JupyterHub 用户指南#

对于未设置 JUPYTER_BOKEH_EXTERNAL_URL 的 Hub,定义一个函数来帮助创建浏览器连接到 Bokeh 服务器的 URL。有关参考实现,请参见下文。您必须修改此代码或将您的 JupyterHub 安装的 URL 分配给环境变量 EXTERNAL_URL。在这种情况下,JupyterHub 默认为 JUPYTERHUB_SERVICE_PREFIX

def remote_jupyter_proxy_url(port):
    """
    Callable to configure Bokeh's show method when a proxy must be
    configured.

    If port is None we're asking about the URL
    for the origin header.
    """
    base_url = os.environ['EXTERNAL_URL']
    host = urllib.parse.urlparse(base_url).netloc

    # If port is None we're asking for the URL origin
    # so return the public hostname.
    if port is None:
        return host

    service_url_path = os.environ['JUPYTERHUB_SERVICE_PREFIX']
    proxy_url_path = 'proxy/%d' % port

    user_url = urllib.parse.urljoin(base_url, service_url_path)
    full_url = urllib.parse.urljoin(user_url, proxy_url_path)
    return full_url

将您上面定义的函数作为 notebook_url 关键字参数传递给 show() 函数。然后,当 Bokeh 设置服务器并创建加载图形的 URL 时,它会调用此函数

show(obj, notebook_url=remote_jupyter_proxy_url)

您可能需要在执行此操作后重启服务器,然后 Bokeh 内容应该加载并执行在您的 Jupyter 环境中定义的 Python 回调。

信任 Notebook#

根据您使用的 Notebook 版本,您可能需要信任 Notebook,以便在 Notebook 关闭并重新打开时重新渲染 Bokeh 绘图。“信任 Notebook”选项通常位于“文件”菜单下

Screenshot of the Jupyter File menu expanded to show the Trust Notebook option.

Notebook 幻灯片#

您可以将带有 Reveal.js 的 Notebook 用于从单元格生成幻灯片。您还可以将独立的(即非服务器)Bokeh 绘图包含在此类幻灯片中。但是,您需要执行一些额外的步骤才能正确显示输出。特别是,请确保包含 output_notebook 的单元格没有被跳过

output_notebook 调用的渲染单元格输出确保 BokehJS 库加载。否则,Bokeh 绘图将无法工作。如果此单元格的类型设置为“跳过”,则 BokehJS 将不会加载,并且 Bokeh 绘图将不会显示。如果您想隐藏此单元格,请为其分配“notes”幻灯片类型。

Notebook 句柄#

您可以在不重新加载已显示绘图的情况下更新它。为此,请将 notebook_handle=True 参数传递给 show(),使其返回句柄对象。您可以将此句柄对象与 push_notebook() 函数一起使用,以使用最近对绘图属性、数据源值等所做的任何更改来更新绘图。

Notebook 句柄功能仅在经典 Jupyter Notebook 中受支持,并且尚未在 JupyterLab 或 Zeppelin 中实现。

以下屏幕截图说明了 Notebook 句柄的基本用法

  1. 导入标准函数和 push_notebook()

Screenshot of Jupyter showing Bokeh push_notebook being imported .
  1. 创建一些绘图并将 notebook_handle=True 传递给 show()

Screenshot of Jupyter with Bokeh content created with notebook comms enabled.
  1. 检查句柄是否与刚刚显示的 In[2] 的输出单元格关联

Screenshot of Jupyter showing the representation of a notebook comms handle in an output cell.
  1. 更新绘图的一些属性,然后使用句柄调用 push_notebook()

Screenshot of Jupyter input cell modifying Bokeh properties and calling push_notebook.
  1. 请注意,In[2] 的输出单元格已更改(无需重新执行)

Screenshot of Jupyter showing the previous plot updated in place, with glyph color white now.

有关 Notebook 句柄用法的更详细示例,请参阅以下 Notebook

Jupyter 交互器#

您可以使用 Notebook 小部件(称为 交互器)来更新 Bokeh 绘图。执行此操作的关键是 push_notebook() 函数。交互器的更新回调调用此函数以从小部件值更新绘图。请参阅下面的 examples/output/jupyter/push_notebook/Jupyter Interactors.ipynb 示例 Notebook 的屏幕截图

Screenshot of Jupyter showing a Bokeh plot together with ipywidget sliders.

更多示例 Notebook#

您可以在 bokeh-tutorial 仓库中找到更多 Notebook 使用示例

  1. 在本地克隆仓库

    git clone https://github.com/bokeh/tutorial.git
    
  2. 在您的 Web 浏览器中启动 Jupyter Notebook。

主要的 Bokeh 仓库还包括一些 Notebook 通信示例

Notebook 外部的 IPyWidgets#

现在您已经了解了如何在 JupyterLab 和经典 Notebook 环境中使用 Bokeh,您可能希望在这些环境之外利用充满活力的 Jupyter 生态系统。您可以使用 Bokeh 的 ipywidgets_bokeh 扩展来实现

$ conda install -c bokeh ipywidgets_bokeh

$ pip install ipywidgets_bokeh

此扩展允许您在 Bokeh 中使用 IPyWidgets。只需将小部件包装在 IPyWidget 模型中,并将包装器添加到文档或将其包含在布局中。您无需安装或启用任何其他扩展。

示例#

按照以下步骤构建一个应用程序,该应用程序具有单个 Jupyter 滑块,该滑块将其调整记录到控制台

  1. 首先构建一个小部件并配置一个观察器

    from ipywidgets import FloatSlider
    angle = FloatSlider(min=0, max=360, value=0, step=1, description="Angle")
    
    def on_change(change):
        print(f"angle={change['new']} deg")
    angle.observe(on_change, names="value")
    
  2. 要将小部件与 Bokeh 集成,请将其包装在 IPyWidget

    from ipywidgets_bokeh import IPyWidget
    ipywidget = IPyWidget(widget=angle)
    
  3. 将包装器添加到 Bokeh 文档

    from bokeh.plotting import curdoc
    doc = curdoc()
    doc.add_root(ipywidget)
    

要运行应用程序,请输入 bokeh serve ipy_slider.py,其中 ipy_slider.py 是应用程序的名称(有关详细信息,请参阅 Bokeh 服务器)。此应用程序可在 https://127.0.0.1:5006/ipy_slider 访问。

您可以基于以上内容构建更复杂的布局,并包含高级小部件,例如 ipyleafletipyvolume。有关更多示例,请参阅 Bokeh 仓库中的 examples/output/jupyter/ipywidgets