今年7月SciPy (python科学计算)2018大会在美国德州奥斯汀举办。会上分享了大量开源Python数据可视化未来的想法和经验。根据会议资料,虫虫做了一些总结,和大家一起分享学习一下。主要是对目前Python数据可视化基本类库的软件分类、包的关联及功能性做了比较分析。

概述

目前常见的Python可视化软件类库(SciVis),基本来源于主要基于1992 OpenGL图形标准,可以提供三维或四维物理过程(3D+随时间变化)的图形密集可视化。该类涉及的工具包括:VisPy,glumpy,GR,Mayavi,ParaView,VTK和yt等。这些类库早于HTML5对富Web应用程序的支持,通常侧重于工程或科学环境中的高性能桌面GUI应用程序。


其他类库基本都属于InfoVis系,专注于空间信息的可视化,不一定三维图形。 InfoVis库打印二维页面或计算机屏幕的两个维度空间抽象解释,通常使用轴和标签。

可视化库谱系

Matplotlib

Matplotlib是2003年发布的最古老,最受欢迎的InfoVis库之一,具有非常广泛的2D绘图类型和输出格式。关于该类库的使用,虫虫之前的文章详细介绍过,关注虫虫,在历史文章中查看。

Matplotlib类库的出现早于HTML5 富Web程序,使用桌面GUI工具包(如Qt和GTK),专注于静态图像及交互式图形。 Matplotlib包含一些3D支持,但比SciVis库提供的限制更多。

Matplotlib系


多年来,Matplotlib的2D绘图功能已经衍生了大量的类库和工具,用于特定类型数据的渲染引擎,也可以用于特定领域(pandas,NetworkX,Cartopy,yt等);提供更高级别的API抽象,用于简化绘图创建(ggplot,plotnine,HoloViews,GeoViews),或者用于其他类型的绘图(seaborn等)扩展。

JavaScript系


HTML5技术的出现,使得浏览器中的富客户端交互性大大加强,其中许多库提供网页和Jupyter Notebooks提供交互式2D图。使用自定义JS(Bokeh,Toyplot)或对诸如D3库的打包(如D3Plotly,bqplot等)。这些打包可以实现轻松添加大型JS图像(Plotly),而使用自定义JS可以定义更低级的JS语法,然后在Python中组合成全新的绘图类型(Bokeh)。

JSON

由于像D3这样的JavaScript库已经成熟,它们的功能大多数都通过JSON规范定义(Vega,Vega-Lite)。基于JSON格式,可以很容易地从任何语言生成JavaScript图,例如Altair和之前的vincent。将完整的绘图规范用JSON提供,可以方便的集成到多种类型的工具中。


WebGL系

HTML5可以用于2D JS绘图,而基于WebGL标准则实现在浏览器和Jupyter的3D图像,由此衍生了three.js(pythreejs,ipyvolume)、vtk.js(itk-jupyter-widgets)和regl(Plotly)。


这些新的基于Web的3D虽然离桌面SciVis 3D库广度和深度还很有距离,但它们可以与Jupyter notebook集成,而且有用Web的易用性,可以轻松实现共享和一次生成随处所用。

其他

还有许多的其他库,不在以上分类里的库,提供了其他方面的补充功能(例如用于可视化网络的graphviz),此处就不再赘述,以后有机会虫虫会陆续撰写相关文章。

功能性比较

按历史和技术进行的上述分类谱系,有助于我们了解和学习当前Python 可视化(viz)包,但是他们之间的关系和差异,更有助于我们对选择使用。该部分我们通过各类库支持的绘图类型,数据大小,用户界面和API类型等方面差异分别介绍。

图形类型

最基本的绘图类型会被绝大多数的类库支持,个别库可能有自己支持独特的图形类型。考虑到库的数量,绘图类型及其随时间的变化,很难精确地描述每个库中支持的内容,详细的支持,我们可以可以从各个库的示例文件中看到。下面我们做个粗略的总结。


统计图(散点图,线,面积,条形图,直方图)

:几乎所有InfoVis库都能很好地支持,其中Seaborn,bqplot,Altair,ggplot2,plotnine的专注于这些图。

图像,常规网格,矩形网格

:Bokeh,Datashader,HoloViews,Matplotlib,Plotly以及大多数SciVis库的支持。

不规则的二维网格(三角网格)

:Matplotlib,Bokeh,Datashader,HoloViews和SciVis库的支持较好。

地理数据

:Matplotlib(Cartopy),GeoViews,ipyleaflet,Plotly

网络/图表

:NetworkX,Plotly,Bokeh,HoloViews,Datashader

3D(网格,散点等)

:SciVis库完全支持,还有Plotly,Matplotlib,HoloViews和ipyvolume的一些支持。

数据大小

每个库的体系结构和基础技术决定了所能支持的数据大小,决定了目标库是否适用于大型图像,视频,多维数组,长时间序列,网格或其他大型的数据集。

SciVis

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

Matplotlib系

:通常可以处理数十万级别数据点的数据集,某些特殊情况下处理更多(取决于后端)。

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窗口,它提供高性能,支持大型数据集以及与其他桌面应用程序集成,但与特定操作系统绑定,通常需要在本地运行,不能通过网络发布。在某些情况下,嵌入基于JavaScript的工具也可以通过嵌入Web浏览器嵌入到本机应用程序中。

导出为HTML

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

Jupyter notebooks

:大多数InfoVis库支持Jupyter notebook的交互式使用。基于ipywidgets的项目提供与Jupyter更紧密的集成,而其他一些类库在Jupyter中仅提供有限的交互性。例如,当与Matplotlib而不是Bokeh一起使用时,仅支持HoloViews。

独立的基于Web的仪表板和应用程序

:Plotly图表可以在具有Dash的单独可部署app中使用,Bokeh,HoloViews和GeoViews可以使用Bokeh Server进行部署。其他大多数的InfoVis库可以使用新的Panel库部署为仪表板,其中包括Matplotlib,Altair,Plotly,Datashader,hvPlot,Seaborn,plotnine和yt。但是由于安全性的考虑,基于ipywidgets的库(ipyleaflet,pythreejs,ipyvolume,bqplot等)很难为面向公众发布,因为Jupyter服务器允许任意代码执行,对外服务存在安全隐患。

API支持

各种InfoVis库提供了大量的API接口,适用于不同类型的用户创建可视化的不同方式。这些API在执行常见任务中需要多少代码以及处理不常见任务。

面向对象的Matplotlib API

:Matplotlib 的API,允许完全控制和组合实现复杂和高度冗长的一些常见任务,如创建子图等。

命令式Pyplot API

: Matplotlib的基本界面允许使用Matlab风格的交互命令,这些命令对于简单的情况而言非常简洁,但是不支持组合,因此限制于一组特定的受支持选项。

Pandasp.lot() API:

以数据框为中心,用户将主要在Pandas中准备数据,然后选择一个子集进行绘图。支持广泛的图表库以及其他数据结构,使它们成为广泛支持的基本绘图命令的有用基本集合。不用直接组合,但可以从底层绘图库返回可组合对象(如hvPlot)。

定义式图形API

:图形风格的库如ggplot,plotnine,Altair和Bokeh,提供了一种自然的方式来组合图形基元,如轴和字形,以创建完整的图。

定义式数据API:

基于其他库的本机API,HoloViews和GeoViews提供了更高级别的数据定义和组合API,专注于注释,描述和处理可视化数据,而不是绘图元素。

这些API中的每一个都适合具有不同背景和目标的用户,使某类的任务变得简介方便。除了Matplotlib之外,大多数库都支持一个或最多两个备用API,因此需要根据用户的技术背景和工作流程选择适宜库。