显示 Altair 图表#

Altair 生成Vega-Lite可视化图表,这需要一个 Javascript 前端来显示图表。由于笔记本环境结合了 Python 后端和 Javascript 前端,许多用户发现它们便于使用 Altair。

Altair 图表可以在Jupyter NotebookJupyterLabZeppelin以及相关的笔记本环境中直接使用,只要有网络连接来加载所需的 javascript 库。

Altair 也可以与各种支持显示 Altair 图表的 IDE 一起使用,并且在大多数平台上,只要启用了相应的前端扩展,就可以离线使用;详细信息如下。

Altair 的渲染器框架#

由于不同的显示系统有不同的要求和限制,Altair 提供了一个 API 来在各种*渲染器*之间切换,以调整 Altair 的图表表示方式。这些可以通过alt.renderers中的渲染器注册表选择。最常用的内置渲染器是

alt.renderers.enable("html")

*(默认)* 输出图表的 HTML 表示。HTML 渲染器在JupyterLabJupyter NotebookZeppelinVSCode-Python和许多相关的笔记本前端中工作,也适用于 Jupyter 生态系统工具,如nbviewernbconvert的 HTML 输出。它需要网络连接来加载相关的 Javascript 库。

alt.renderers.enable("mimetype")

*(Altair 4.0 之前的默认设置):* 输出 vega-lite 特定的 mime 类型,可以由相应的前端扩展解释以显示图表。这也会输出绘图的 PNG 表示,这对于离线或在不支持渲染 vegaspecs 的平台(如 GitHub)上查看绘图很有用。它适用于较新版本的JupyterLabnteractVSCode-Python,但不适用于Jupyter Notebook,也不适用于nbviewernbconvert等工具。

alt.renderers.enable("jupyter")

*(版本 5.3 新增):* 使用JupyterChart输出图表。此渲染器兼容支持第三方 Jupyter Widgets 的环境,包括JupyterLabJupyter NotebookVSCode-PythonColab。它需要网络连接来加载相关的 Javascript 库。请注意,尽管此渲染器使用JupyterChart,但它不提供在 Python 中访问值和选择参数的功能。为此,请遵循JupyterChart文档中的说明,明确创建一个JupyterChart对象。

alt.renderers.enable("jupyter", offline=True)

*(版本 5.3 新增):* 与上述"jupyter"渲染器相同,但从vl-convert-python包(而不是在线 CDN)加载 JavaScript 依赖项,因此不需要互联网连接。

alt.renderers.enable("browser")

*(版本 5.3 新增):* 在外部网络浏览器中显示图表。当在本地非 Jupyter 环境中使用 Vega-Altair 时,例如在IPythonSpyder中,此渲染器特别有用。有关更多信息,请参阅浏览器渲染器

此外,Altair 还包括以下渲染器

  • "default""colab""kaggle""zeppelin":与"html"相同

  • "jupyterlab""nteract":与"mimetype"相同

  • "png":渲染器,将图表渲染并转换为 PNG,使用"image/png" MIME 类型输出。

  • "svg":渲染器,将图表渲染并转换为 SVG 图像,使用"image/svg+xml" MIME 类型输出。

  • "olli":使用Olli生成用于屏幕阅读器用户的可访问文本结构的渲染器。

  • "json":输出原始 JSON 图表规范的渲染器,使用"application/json" MIME 类型。

您可以使用alt.renderers.names()将所有已注册的渲染器作为 Python 列表返回。

其他渲染器可以通过 Python 的 entrypoints 系统由第三方包安装,或者您可以创建自己的渲染器,请参阅自定义渲染器

在 JupyterLab 中显示#

JupyterLab 1.0 及更高版本可以在有实时网络连接的情况下与 Altair 的默认渲染器一起工作:无需启用渲染器步骤。

或者,为了在 JupyterLab 中离线渲染,您可以使用 mimetype 渲染器

# Optional in JupyterLab: requires an up-to-date vega labextension.
alt.renderers.enable('mimetype')

并确保您安装了正确版本的 vega labextension;对于 Altair 4,可以使用以下命令安装

$ jupyter labextension install @jupyterlab/vega5-extension

在 JupyterLab 2.0 或更高版本中,此扩展默认安装,尽管 JupyterLab 发布版本中可用的版本通常需要几个月才能跟上新的 Altair 版本。

在 Jupyter Notebook 中显示#

经典的 Jupyter Notebook 可以在有实时网络连接的情况下与 Altair 的默认渲染器一起工作:无需启用渲染器步骤。

或者,为了在 Jupyter Notebook 中离线渲染,您可以使用 notebook 渲染器

# Optional in Jupyter Notebook: requires an up-to-date vega nbextension.
alt.renderers.enable('notebook')

此渲染器由ipyvega notebook 扩展提供,可以使用 pip 安装并启用

$ pip install vega

或 conda

$ conda install vega --channel conda-forge

在较旧版本的 notebook(<5.3)中,您需要额外启用该扩展

$ jupyter nbextension install --sys-prefix --py vega

在 nteract 中显示#

nteract无法 natively 显示 HTML 输出,因此 Altair 的默认html渲染器将无法工作。然而,nteract 原生包含基于 vega 和 vega-lite mimetype 的渲染。要在 nteract 中使用 Altair,请确保您使用的版本支持 Vega-Lite v5 mimetype,并使用

alt.renderers.enable('mimetype')

在 VSCode 中显示#

在 VSCode 中显示#

VSCode-Python可以在有实时网络连接的情况下与 Altair 的默认渲染器一起工作:无需启用渲染器步骤。

# Optional in VS Code
alt.renderers.enable('mimetype')

或者,为了离线渲染,您可以使用 mimetype 渲染器

仪表盘#

Altair 与常见的 Python 仪表盘包兼容。其中许多甚至支持从图表中读取参数。这使您可以例如选择数据点,并根据该选择更新仪表盘的另一部分,例如表格。

软件包

显示交互式 Altair 图表

支持读取参数

Panel

Panel

Panel

Panel

Panel

Panel

Plotly Dash

Panel

Panel

Panel

Panel

Jupyter Voila使用JupyterChart

Panel

Panel

Panel

Panel

Marimo

Shiny使用JupyterChart

alt.renderers.enable("svg")

Solara

alt.renderers.enable("png")

  • Streamlit

alt.renderers.enable("png", scale_factor=2, ppi=144)

上述提到的框架都需要您在服务器上运行一个 Web 应用程序,如果您想与他人分享您的工作。Web 应用程序提供了很多灵活性,例如您可以根据仪表盘中下拉菜单的值从数据库中获取数据。然而,它也带来了一些复杂性。对于 Altair 本身提供的交互性已经足够的使用场景,您也可以使用生成不需要 Web 服务器的 HTML 页面的工具,例如QuartoJupyter Book

如果您使用的仪表盘包未在此列出,请在 GitHub 上提出一个 issue,以便我们可以添加它。

在没有 JavaScript 前端的环境中使用#

alt.renderers.enable("browser")

Altair 生成的 Vega-Lite 规范可以在任何 Python 环境中生成,但要渲染这些规范目前需要一个 JavaScript 引擎。因此,Altair 在上述基于浏览器的环境中工作最顺畅。即便如此,Altair 也可以使用下面描述的方法在非基于浏览器的环境中有效使用。

  • 静态图像渲染器#

  • "png""svg"渲染器依赖于嵌入在 vl-convert 可选依赖项中的 JavaScript 引擎,从 Vega-Lite 图表规范生成静态图像。然后使用 Mime 渲染器扩展系统在基于 IPython 的环境中显示这些静态图像。此方法可用于在IPython QtConsoleSpyder中内联显示 Altair 图表的静态版本,以及在基于浏览器的环境(如 JupyterLab)中显示。

  • "svg"渲染器这样启用

局限性

  • "png"渲染器这样启用

  • 在基于 IPython 的环境中,当图表是单元格或命令的最终值时,"browser" 渲染器将自动在浏览器中打开图表。这种行为在标准的 python REPL 中不可用。在这种情况下,可以使用 chart.show() 方法手动调用活动渲染器并在浏览器中打开图表。

  • "png"渲染器支持以下关键字参数配置选项

手动 save() 和显示#

scale_factor参数可用于按指定的比例因子增加图表大小(默认为 1.0)。

ppi参数控制显示图像的每英寸像素(PPI)分辨率(默认为 72)。

示例用法

本节总结了一些最常见的问题及其解决方案。

浏览器渲染器#

为了支持在非基于浏览器的环境中显示具有交互功能的图表,"browser"渲染器会自动在系统 Web 浏览器的标签页中打开图表。

"browser"渲染器这样启用

  1. 您使用的是不支持 JavaScript 的 ECMAScript 6 的旧浏览器:在这种情况下,图表可能无法正常显示或完全不显示。例如,Altair 图表在任何版本的 Internet Explorer 中都不会渲染。如果出现这种情况,您可能会在浏览器的 Javascript 控制台中看到语法错误。

  2. "browser"渲染器支持以下关键字参数配置选项

  3. 您可能未能触发 notebook 的显示机制(见下文)。

using参数可用于指定使用哪个系统 Web 浏览器。可以设置为字符串来指示必须使用的单个浏览器(例如"safari"),或者可以设置为浏览器名称列表,使用列表中第一个可用的浏览器。请参阅webbrowser 模块的文档,了解支持的浏览器名称列表。如果未指定,则使用系统默认浏览器。

offline参数可用于指定 JavaScript 依赖项应从在线 CDN 加载还是与图表规范一起嵌入。当offlineFalse(默认值)时,JavaScript 依赖项从在线 CDN 加载,因此需要互联网连接。当offlineTrue时,JavaScript 依赖项与图表规范一起嵌入,因此无需互联网连接。将offline设置为True需要可选的vl-convert-python依赖项。

>>> x = 4  # no output here
>>> x      # output here, because x is evaluated
4
>>> x * 2  # output here, because the expression is evaluated
8

port参数可用于配置图表 HTML 服务使用的系统端口。默认为随机开放端口。

import altair as alt
from vega_datasets import data
cars = data.cars.url

chart = alt.Chart(cars).mark_point().encode(
    x='Horsepower:Q',
    y='Miles_per_Gallon:Q',
    color='Origin:N',
)

限制

chart = alt.Chart(cars).mark_point().encode(
    x='Horsepower:Q',
    y='Miles_per_Gallon:Q',
    color='Origin:N',
)

chart

"browser"渲染器会建立一个临时的 Web 服务器,它只提供一次图表服务,然后打开指定的浏览器指向服务器的 URL。这种方法不需要在磁盘上创建临时 HTML 文件,而且内存效率高,因为不需要长时间运行的 Web 服务器进程。这种方法的局限性是如果浏览器刷新,图表将会丢失,并且无法复制图表 URL 并将其粘贴到另一个浏览器标签页中。

alt.Chart(cars).mark_point().encode(
    x='Horsepower:Q',
    y='Miles_per_Gallon:Q',
    color='Origin:N',
)

在基于 IPython 的环境中使用时,当图表是单元格或命令的最终值时,"browser"渲染器会自动在浏览器中打开图表。此行为在标准python REPL 中不可用。在这种情况下,可以使用chart.show()方法手动调用活动渲染器并在浏览器中打开图表。

此渲染器与远程环境(如BinderColab)不兼容。

import altair as alt

alt.Chart('nonexistent_file.csv').mark_line().encode(
    x='x:Q',
    y='y:Q',
)

手动save()和显示#

  1. 如果您愿意,可以先将图表保存到文件(html、png 等),然后再显示。有关更多信息,请参阅保存 Altair 图表

  2. 故障排除#

Altair 有许多活动部件:它在 Python 中创建数据结构,这些结构被传递到前端渲染器,然后渲染器运行 JavaScript 代码生成输出。这种复杂性意味着可能出现一些情况,导致事情不像预期那样立即工作。

本节总结了一些最常见的问题及其解决方案。

一般故障排除#

图表完全不显示#

如果您期望看到图表输出但完全没有看到任何内容,这意味着 Javascript 渲染库没有被调用。这可能由以下几个原因引起

您的浏览器太旧,不支持 JavaScript 的ECMAScript 6:在这种情况下,图表可能无法正常显示或完全不显示。例如,Altair 图表无法在任何版本的 Internet Explorer 中渲染。如果出现这种情况,您可能会在浏览器的Javascript Console中看到语法错误。

$ python -m http.server
您的浏览器无法加载 javascript 库。这可能是由于本地防火墙、广告拦截器或浏览器离线所致。检查您浏览器的Javascript Console,查看是否有错误。

您可能未能触发笔记本的显示机制(见下文)。

如果您在笔记本环境中工作,图表只有在**单元格的最后一行计算结果为一个图表对象**时才会显示

import pandas as pd

data = pd.DataFrame({'x': [1, 2, 3],
                     'y': [3, 1, 4]})

alt.Chart(data).mark_point().encode(
    x='x:Q',
    y='y:Q',
    color='color:Q'  # <-- this field does not exist in the data!
  )

类比一下,考虑简单的 Python 操作的输出

带有特殊字符的编码#

Altair 所基于的 Vega-Lite 语法允许编码名称使用特殊字符来访问嵌套属性(参见 Vega-Lite 的 Field 文档)。

如果您输入的最后一行是一个赋值操作,则不会显示任何输出。Altair 图表也是如此。

import pandas as pd
data = pd.DataFrame({'x.value': [1, 2, 3]})

alt.Chart(data).mark_point().encode(
    x='x.value:Q',
)

要直接绘制此数据,必须转义字段名称中的句点

import pandas as pd
data = pd.DataFrame({'x.value': [1, 2, 3]})

alt.Chart(data).mark_point().encode(
    x=r'x\.value:Q',
)

最后一条语句是赋值,因此没有输出,图表也没有显示。如果您将图表赋值给一个变量,则需要以对该变量的求值结束单元格

在 JupyterLab 中排除故障#

或者,您可以直接对图表进行求值,而不是将其赋值给变量,在这种情况下,对象定义本身就是最后一条语句,并将作为输出显示

绘图显示,但内容为空#

有时图表可能会出现,但内容为空;例如

最简单的解决方案是使用默认渲染器

alt.renderers.enable('default')

如果出现这种情况,通常意味着以下两种情况之一

您的数据是通过一个无效或无法访问的 URL 指定的

您的编码与数据源中的列不匹配

在上面的示例中,nonexistent_file.csv不存在,因此图表无法渲染(相关的警告将在Javascript Console中可见)。

可能导致此问题的其他一些特定情况

<VegaLite 3 object>

您启用了广告拦截器

$ jupyter lab --version
1.2.0

通过 URL 引用数据的图表有时可能会触发浏览器广告拦截器的误报。检查您的浏览器的Javascript Console是否有错误,并尝试禁用您的广告拦截器。

您正在进行跨域加载数据

如果您将图表保存为 HTML 并使用浏览器中的file:// URL 打开它,大多数浏览器将不允许 javascript 从http://域加载数据集。这是您浏览器中的一项安全功能,无法禁用。要本地查看此类图表,一个好的方法是使用像 Python 提供的简单本地 HTTP 服务器

JavaScript output is disabled in JupyterLab

它可能意味着两件事情之一有问题

  1. 您的编码与数据不匹配

    import altair as alt
    alt.__version__
    

    如果您引用的字段在数据中不存在,无论是由于字段名称拼写错误,还是因为列包含特殊字符(见下文),都会导致类似的空白图表。

  2. 以下是一个字段名称指定错误导致空白图表的示例

    import altair as alt
    print(alt.renderers.active)
    

    只有当活动渲染器为 "default""jupyterlab" 时,JupyterLab 渲染才会工作。您可以通过运行以下命令重新启用默认渲染器

    import altair as alt
    alt.renderers.enable('default')
    

    Altair 不检查字段是否有效,因为在完整的 schema 中可以通过多种途径指定字段,很难考虑所有极端情况。改进用户体验是当务之急;请参阅vega/vega-lite#3576

带特殊字符的编码#

Altair 基于的 Vega-Lite 语法允许编码名称使用特殊字符访问嵌套属性(请参阅 Vega-Lite 的字段文档)。

这可能导致在 Altair 中尝试在图表中使用此类列时出错。例如,以下图表无效

Chart({
  data: 'https://vega.github.io/vega-datasets/data/cars.json',
  encoding: FacetedEncoding({
    x: X({
      shorthand: 'Horsepower'
    })
  }),
  mark: 'point'
})

这可能意味着您正在使用较旧的 Jupyter 内核。您可以通过运行以下命令确认这一点

import IPython; IPython.__version__
# 6.2.1

要直接绘制此数据,必须转义字段名称中的点号

解决此问题最简单的方法是更改您的内核:选择“Kernel”(内核)->“Change Kernel”(更改内核),然后使用出现的第一个内核。

一般来说,最好在数据源中尽可能避免使用特殊字符,如".""[""]"

在 JupyterLab 中故障排除#

Javascript Error: require is not defined

VegaLite 4/5 对象#

alt.renderers.enable('default')

*如果您使用的是 Jupyter notebook 而不是 JupyterLab,请参阅* Notebook:VegaLite 4/5 对象

如果您使用 JupyterLab(而不是 Jupyter notebook)并看到提及VegaLite 4 objectVegaLite 5 object的错误消息,则意味着您已启用了mimetype渲染器,但您的 JupyterLab 前端不支持 VegaLite 4 或 5 mimetype。

最简单的解决方案是使用默认渲染器

如果您使用的是 Jupyter Notebook(而非 JupyterLab)并看到提及 VegaLite 4 objectVegaLite 5 object 的错误消息,则表示您已启用了 mimetype 渲染器。最简单的解决方案是使用默认渲染器

alt.renderers.enable('default')

如果出现这种情况,通常意味着以下两种情况之一

并重新运行包含图表的单元格。

如果您想在 JupyterLab 中使用 mimetype 渲染,请使用pip install -U jupyterlabconda update jupyterlab将 JupyterLab 更新到最新版本。

VegaLite 3 对象#

<Vegalite 3 object>

*如果您使用的是 Jupyter notebook 而不是 JupyterLab,请参阅* Notebook:VegaLite 3 对象

  1. 如果您使用 JupyterLab(而不是 Jupyter notebook)并看到以下输出

    import altair as alt
    alt.renderers.enable('notebook')
    

    以便在经典 notebook 中渲染图表。

    这很可能意味着您使用的 JupyterLab 版本太旧。Altair 3.0 或更高版本最适合 JupyterLab 1.0 或更高版本;使用以下命令检查版本

    NoSuchEntryPoint: No 'notebook' entry point found in group 'altair.vegalite.v2.renderer'
    

    这意味着您尚未安装 vega 包。如果看到此错误,请务必按照 在 Jupyter Notebook 中显示 中的标准安装说明进行操作。

  2. 如果您使用的是旧版本的 jupyterlab,则使用pip install -U jupyterlabconda update jupyterlab更新 JupyterLab,具体取决于您最初的安装方式。

    $ jupyter notebook --version
    

    JupyterLab 中 JavaScript 输出被禁用#

如果您使用 JupyterLab 并看到以下输出

Notebook:文本图表表示#

这可能意味着以下两种情况之一有问题

您使用的 Altair 版本太旧。JupyterLab 仅支持 Altair 2.0 或更高版本;您可以在笔记本代码单元格中执行以下命令检查 altair 版本

如果您正在使用 Jupyter notebook 并看到类似于此的图表对象的文本表示

Chart({
  data: 'https://vega.github.io/vega-datasets/data/cars.json',
  encoding: FacetedEncoding({
    x: X({
      shorthand: 'Horsepower'
    })
  }),
  mark: 'point'
})

这可能意味着您正在使用较旧的 Jupyter 内核。您可以通过运行以下命令确认这一点

import IPython; IPython.__version__
# 6.2.1

要直接绘制此数据,必须转义字段名称中的点号

如果版本早于 2.0,则退出 JupyterLab 并按照在 JupyterLab 中显示中的安装说明进行操作。

您启用了错误的渲染器。JupyterLab 支持默认渲染器,但如果您使用alt.renderers.enable()启用了其他渲染器,图表将无法在 JupyterLab 中正确渲染。您可以通过运行以下命令检查哪个渲染器处于活动状态

如果您在 Jupyter notebook 环境之外使用 Altair(例如 Python 或 IPython 终端),图表将以文本表示形式显示。渲染 Altair 图表需要执行 Javascript 代码,而您的 Python 终端无法原生执行此操作。

只有当活动渲染器是"default""jupyterlab"时,JupyterLab 渲染才会起作用。您可以通过运行以下命令重新启用默认渲染器