Python 数据可视化 2018:为何有如此多的库?

本文是关于 Python 数据可视化工具现状以及 SciPy 2018 展会趋势的三篇系列文章中的第一篇。

作者:James A. Bednar

在奥斯汀 SciPy 2018 的特别会议上,各种开源 Python 可视化工具的代表分享了他们对 Python 数据可视化未来发展的愿景。我们听取了关于 MatplotlibPlotlyVisPy 等诸多工具的最新进展。我作为 PyVizGeoViewsDatashaderPanelhvPlotBokeh 的代表参加了 SciPy 2018,我的 Anaconda 同事 Jean-Luc Stevens 代表 HoloViews 出席了会议。这第一篇文章概述了当前可用的软件包,并展示了它们之间的联系,后续文章将讨论这些工具近年来是如何发展的,以及它们未来的发展方向。

当前格局

为了奠定基础,我展示了 Jake VanderPlas 对当前 Python 中众多不同可视化库之间关系的概述

python's visualization landscape

在这里,您可以看到几个主要的库群,每个库群都有不同的起源、历史和重点。一个清晰可分离的群体是用于可视化物理位置数据的“SciVis”库(在图的左下方)。这些工具(VisPyglumpyGRMayaviParaViewVTKyt)主要基于 1992 年的 OpenGL 图形标准,为规则或不规则网格数据提供三维或四维(3D 随时间变化)物理过程的图形密集型可视化。这些库早于 HTML5 对富 Web 应用程序的支持,通常专注于工程或科学领域的高性能桌面 GUI 应用程序。

其他库几乎都属于“InfoVis”组,专注于任意空间中信息的可视化,不一定是三维物理世界。InfoVis 库利用印刷页面或计算机屏幕的二维空间来解释抽象空间,通常带有轴和标签。InfoVis 库可以进一步细分为多个子组

Matplotlib

Matplotlib 是 InfoVis 库中最古老且最受欢迎的库之一,于 2003 年发布,具有非常广泛的 2D 绘图类型和输出格式。Matplotlib 也早于 HTML5 对富 Web 应用程序的支持,而是专注于用于发布的静态图像以及使用 Qt 和 GTK 等桌面 GUI 工具包的交互式图形。Matplotlib 包含一些 3D 支持,但远不如 SciVis 库提供的支持广泛。

基于 Matplotlib

多年来,各种工具都建立在 Matplotlib 的 2D 绘图功能之上,要么将其用作特定类型数据或特定领域的渲染引擎(pandasNetworkXCartopyyt 等),要么在其之上提供更高级别的 API 以简化绘图创建(ggplotplotnineHoloViewsGeoViews),或者使用其他类型的绘图对其进行扩展(seaborn 等)。

JavaScript

一旦 HTML5 允许浏览器中的富交互性,就出现了许多库,为网页和 Jupyter notebooks 提供交互式 2D 绘图,要么使用自定义 JS (BokehToyplot),要么主要封装现有的 JS 库(如 D3 (Plotlybqplot))。封装现有的 JS 可以轻松添加为大型 JS 市场创建的新绘图(如 Plotly),而使用自定义 JS 允许定义较低级别的 JS 原语,这些原语可以从 Python 内部组合成全新的绘图类型(如 Bokeh)。

JSON

随着 D3 等 JavaScript 库的成熟,它们的功能已被捕获在声明式 JSON 规范中(VegaVega-Lite),从而可以轻松地从任何语言生成 JavaScript 绘图,现在包括 Python(通过 Altair 以及之前的 vincent)。将完整的绘图规范作为可移植的 JSON 提供,允许跨多种类型的工具进行集成。

WebGL

正如 HTML5 为 2D JavaScript 绘图所做的那样,WebGL 标准使浏览器和 Jupyter 中的 3D 交互成为可能,从而产生了基于 three.js (pythreejsipyvolume)、vtk.js (itk-jupyter-widgets) 或 regl (Plotly) 构建的浏览器内 3D 绘图。这些较新的基于 Web 的 3D 方法都无法达到桌面 SciVis 3D 库的广度和深度,但它们确实允许与 Jupyter notebooks 完全集成,并通过 Web 实现轻松共享和远程使用。因此,即使 WebGL 工具与 SciVis 工具有一些共同的应用,它们也可能与其他 InfoVis 工具更紧密地联系在一起。

其他

许多其他库,甚至超出 Jake 图表中列出的库,都提供了其他补充功能(例如,用于可视化网络的 graphviz)。

可视化工具之间的区别因素

上述按历史和技术的分类有助于解释我们如何发展到当前 Python 可视化软件包的激增,但它也有助于解释为什么各种软件包之间在用户级功能方面存在如此大的差异。具体来说,在支持的绘图类型、数据大小、用户界面和 API 类型方面存在重大差异,这使得库的选择不仅仅是个人偏好或便利性的问题,因此它们非常重要,需要理解

绘图类型

最基本的绘图类型在多个库之间共享,但其他类型仅在某些库中可用。鉴于库的数量、绘图类型及其随时间的变化,很难精确描述每个库中支持的内容,但如果您查看每个库的示例库,通常可以清楚地了解其重点。作为一个粗略的指南

统计图(散点图、折线图、面积图、条形图、直方图):几乎所有 InfoVis 库都很好地覆盖了这些类型,但它们是 Seaborn、bqplot、Altair、ggplot2、plotnine 的主要重点

图像、规则网格、矩形网格:Bokeh、Datashader、HoloViews、Matplotlib、Plotly 以及大多数 SciVis 库都很好地支持这些类型

不规则 2D 网格(三角形网格):SciVis 库以及 Matplotlib、Bokeh、Datashader、HoloViews 都很好地支持这些类型

地理数据:Matplotlib(使用 Cartopy)、GeoViews、ipyleaflet、Plotly

网络/图:NetworkX、Plotly、Bokeh、HoloViews、Datashader

3D(网格、散点等):SciVis 库完全支持,Plotly、Matplotlib、HoloViews 和 ipyvolume 也提供一些支持。

数据大小

每个库的架构和底层技术决定了支持的数据大小,从而决定了该库是否适用于大型图像、电影、多维数组、长时序数据、网格或其他大型数据集

SciVis:通常可以使用编译的数据库和本机 GUI 应用程序处理非常大的网格数据集,达到千兆字节或更大。

基于 Matplotlib:通常可以处理数十万个点,性能合理,在某些特殊情况下可以处理更多(例如,取决于后端)。

JSON:在没有特殊处理的情况下,JSON 基于文本的数据编码将基于 JSON 的规范限制为 几千个点到几十万个点,这是因为文件大小和所需的文本处理。

JavaScript:ipywidgets、Bokeh 和 Plotly 都使用 JSON,但使用额外的二进制数据传输机制对其进行增强,以便它们可以处理数十万到数百万个数据点。

WebGL:使用 HTML Canvas 的 JavaScript 库在性能良好时最多只能处理数十万个点,但 WebGL(通过 ipyvolume、Plotly 以及在某些情况下通过 Bokeh)允许处理数百万个点。

服务器端渲染:来自 Datashader 或 Vaex 的外部 InfoVis 服务器端渲染允许在 Web 浏览器中处理数十亿、数万亿或更多数据点,方法是将任意大的分布式或核外数据集转换为固定大小的图像以嵌入到客户端浏览器中。

由于这些类型的库支持的数据大小(以及在某种程度上数据类型)范围很广,因此需要处理大型数据的用户需要在开始时选择合适的库。

用户界面和发布

各种库在使用绘图的方式上差异很大。

静态图像:大多数库现在都可以无头运行以创建静态图像,至少可以创建 PNG 格式,通常可以创建平滑的矢量格式,如 SVG 或 PDF。

本机 GUI 应用程序:SciVis 库以及 Matplotlib 和 Vaex 可以创建特定于操作系统的 GUI 窗口,这些窗口提供高性能、对大型数据集的支持以及与其他桌面应用程序的集成,但它们与特定操作系统绑定,通常需要在本地而不是通过 Web 运行。在某些情况下,基于 JavaScript 的工具也可以通过嵌入 Web 浏览器嵌入到本机应用程序中。

导出到 HTML:大多数 JavaScript 和 JSON 库都可以在无服务器模式下运行,从而生成交互式绘图(缩放、平移等),这些绘图可以通过电子邮件发送或发布在 Web 服务器上,而无需 Python 可用。

Jupyter notebooks:大多数 InfoVis 库现在都支持在 Jupyter notebooks 中进行交互式使用,其中基于 JavaScript 的绘图由 Python 提供支持。基于 ipywidgets 的项目提供了与 Jupyter 更紧密的集成,而其他一些方法仅在 Jupyter 中提供有限的交互性(例如,当 HoloViews 与 Matplotlib 而不是 Bokeh 一起使用时)。

独立的基于 Web 的仪表板和应用程序:Plotly 图表可以与 Dash 一起在单独的可部署应用程序中使用,而 Bokeh、HoloViews 和 GeoViews 可以使用 Bokeh Server 进行部署。大多数其他 InfoVis 库可以使用新的 Panel 库部署为仪表板,至少包括 Matplotlib、Altair、Plotly、Datashader、hvPlot、Seaborn、plotnine 和 yt。然而,尽管基于 Web 的交互性,基于 ipywidgets 的库(ipyleaflet、pythreejs、ipyvolume、bqplot)很难部署为面向公众的应用程序,因为 Jupyter 协议允许任意代码执行(但请参阅已废弃的 Jupyter dashboards 项目和 flask-ipywidgets 以获取潜在的解决方案)。

因此,用户需要考虑给定的库是否涵盖他们期望的可视化用途范围。

API 类型

各种 InfoVis 库提供了各种各样的编程接口,适用于非常不同类型的用户和创建可视化的不同方式。这些 API 在执行常见任务所需的代码量以及它们为用户处理不常见任务以及将原语组合成新型绘图类型提供的控制量方面,差异巨大。

面向对象的 Matplotlib APIMatplotlib 的主要 API,允许完全控制和可组合性,但对于某些常见任务(如创建子图)而言,复杂且非常冗长。

命令式 Pyplot APIMatplotlib 的基本接口 允许 Matlab 风格的命令式命令,对于简单情况而言简洁明了,但不可组合,因此在很大程度上仅限于一组特定的支持选项。

命令式 Pandas .plot() API:以数据帧为中心,用户主要在 Pandas 中准备数据,然后选择一个子集进行绘图。正如本系列下一篇文章中将讨论的那样,现在支持各种图表库以及其他数据结构,使其成为一套有用的、广泛支持的基本绘图命令。不直接可组合,但可以从底层绘图库返回可组合对象(如 hvPlot)。

声明式图形 API:受图形语法启发的库,如 ggplot、plotnine、Altair 和(在某种程度上)Bokeh,提供了一种自然的方式来组合图形基元(如坐标轴和字形)以创建完整的绘图。

声明式数据 API:HoloViews 和 GeoViews 基于其他库的原生 API 构建,提供了更高级别的声明式和组合式 API,专注于注释、描述和处理可视化数据,而不是绘图元素。

这些 API 各自适用于具有不同背景和目标的用户,使得某些任务变得简单明了,而另一些任务则更具挑战性。除了 Matplotlib 之外,大多数库最多支持一到两个替代 API,因此选择一个其方法符合用户技术背景和首选工作流程的库至关重要。

新兴趋势

正如您所看到的,Python 提供了非常广泛的可视化功能,其方法和重点的多样性反映在大量可用的库中。方法之间的差异仍然很重要,并且具有深远的影响,这意味着用户在深入研究任何特定方法之前需要考虑这些差异。但是,正如我们在 SciPy 2018 上看到的那样,趋同趋势正在帮助降低用户选择哪个库的重要性。要了解有关这些新兴趋势的更多信息,请继续关注本系列的第二部分Python 数据可视化 2018:迈向融合

与专家交谈

与我们的一位专家交谈,为您的 AI 之旅找到解决方案。

与专家交谈