在奥斯汀举行的SciPy2018特别会议上,许多开源Python可视化工具的代表分享了他们对于Python数据可视化未来发展的不同观点。我们听到了关于Matplotlib,Plotly以及VisPy等的更新。我作为PyViz,GeoViews,Datashader,Panel,hvPlot和Boken的代表参加了SciPy2018特别会议,我Anaconda的同事Jean-Luc Stevens 代表HoloViews参加了该会议。本文调查了当前可用的软件包并展示了他们之间的联系方式,后续的文章将会讨论近年来这些工具如何发展以及未来如何发展。
当前的景观
为了表达清楚,我展示了Jake VanderPlas对于当前Python中不同库之间如何相互联系的概述:
在这里,你能看到几个主要的库组,每一个库都有不同的起点,历史以及着重点。“SciVis”是一个可分离的库组,主要用于物理位置数据的可视化(在图的左下方)。这些工具(VisPy,glummpy,GR,Mayavi,paraView,VTK以及yt)主要是基于1992年OpenGL图形标准而建立,以三维或四维(3D随时间变化)形式对物理进程进行图形密集型的可视化,用于常规或非常规的格网数据。这些库出现的时间早于HTML5对丰富的网络应用程序的支持,通常侧重于工程领域或科学背景下的高性能桌面GUI应用程序。
其它的库几乎都来自于“InfoVis”库组,主要侧重在任意空间信息的可视化,并非必需来自于三维物理世界。InfoVis库使用打印页面或计算机屏幕的两个维度解译抽象空间,通常使用轴和标签。InfoVis库可以被细分成许多的子库:
Matplotlib
Matplotlib于2003年发布,拥有非常广泛的2D绘图类型和输出格式,是最古老以及到目前为止最受欢迎的InfoVis库之一。Matplotlib也出现于HTML5对丰富的网络应用支持之前,侧重于使用桌面GUI工具包(如Qt和GTK)的静态图像以及图形交互。Matplotlib提供一些3D支持功能,但是相较于SciVis库提供的3D支持功能而言受到更多的限制。
Matplotlib-based
近年来,基于Matplotlib的2D绘图能力已经建立了多样化的工具,既可以作为一个渲染引擎针对特定的数据类型或特定的领域(pandas,NetworkX,Cartopy以及yt等)使用,也可以提供一个更高级别的API简化绘图创造(ggplot,plotnine,HoloViews,GeoViews),或是用其它的绘图类型(seaborn等)对其进行扩展。
JavaScript
一旦HTML5在浏览器之间实现了丰富的交互性,许多库就能够开始在网页或Jupyter笔记本上提供交互性的2D绘图,也可以使用自定义的JS(Boken,Toyplot)或封装好的现有的JS库,如D3(Plotly,bqplot)。封装现有的JS使得添加为大型JS市场(如Plotly)创造的新图变得十分容易,而使用自定义Js可以定义低级别的Js基原,这些基原在Python中可以被组合成全新的绘图类型(对于Bokeh而言)。
JSON
随着JavaScript库如D3逐渐发展完善,他们的功能也出现在声明型JSON规范中(Vega,Vega-Lite),从而使得在任何语言中生成JavaScript图形变得更加简单,现在也包括Python语言(通过Altair,以前通过vincent)。完整的绘图规范可以作为可移植JSON使用,从而支持跨多种工具的集成。
WebGL
就像HTML5用于2D JavaScript绘图一样,WebGL标准实现了浏览器和Jupyter的3D交互,致使基于three.js(pythreejs,ipyvolume),vtk.js(itk-jupyter-widgets)或regl(Plotly)建立了3D浏览器内置绘图。这些基于网络的新的3D方法都没有接近桌面SciVis 3D库的广度和深度,但是他们允许与Jupyter笔记本的深度融合,并通过网络实现简单的共享以及使用。因此,即使WebGL工具有一些应用与SciVis工具相同,但他们可能与其他的InfoVis工具联系更紧密。
其它
许多其他的库,甚至在Jake的表格之外的库,提供了其它的补充性的功能(例如用于可视化网络的graphviz)。
Viz 工具之间的区别
上述按照历史和技术分类的方法有助于解释我们如何获得Python viz包的当前数量,但是它也有助于解释为什么不同的包之间用户水平的差异如此巨大。具体来说,主要的差异存在于所支持的绘图类型、数据规模、用户界面,这些差异使得库的选择不仅仅是个人喜好或方便的问题,因此理解他们非常重要:
绘图类型
最基本的绘图类型在多个库之间共享,但是其它的绘图类型仅在某些库中可用。考虑到库的数量、绘图类型以及他们随时间的变化,精确的描绘出每一个库所支持的内容是十分困难的,但是如果你查看每一个库的范例,你通常可以清楚的看到其重点是什么。
作为一个粗略的指南:
统计图(散点图、直线图、区域图、条形图、直方图):几乎所有的InfoVis库都覆盖了这些图,但这些图是Seaborn、bqplot、Altair、广告牌咯他、plot9的主要关注点。
图像,规则格网,矩形网格:Boken,Datashader,HoloViews,Matplotlib,Plotly以及大多数的SciVis库都能够很好的支持。
不规则的二维网格(三角形网格):由SciVis库和Matplotlib,Bokeh,data hader,HoloViews支持。
地理数据:Matplotlib(附带Cartopy),GeoViews,ipyleaflet,plot
网络/图形:NetworkX,,Plotly, Bokeh, HoloViews, Datashader
3D(网格,散点等):SciVis库完全支持,并在Plotly,Matplotlib,HoloViews和ipyvolume中提供一些支持。
数据大小
每个库的架构和底层技术决定了其所支持的数据规模大小,从而决定了该库是否适合于大型图像、电影、多维数组、长时间序列、网格或其他大型数据集:
SciVIs:使用汇编的数据库和本地GUI应用程序通常可以处理非常大的网格数据集,千兆字节或更大。
基于matplotlib:通常可以平稳的处理数十万个点,在某些特殊情况下甚至更多(例如,取决于后端)。
JSON:没有特殊处理,JSON基于文本的数据编码将基于JSON的规范限制在几千点到几十万点,这是由于所需的文件大小和文本处理。
JavaScript:ipywidgets,Bokeh和Plotly都使用JSON,但使用额外的二进制数据传输机制来增强它,以便它们可以处理数十万到数百万个数据点。
WebGL:使用HTML画布的JavaScript库为了获得良好的性能,最多只能提供几十万个点,但是WebGL(通过ipyvolume,Plotly和在某些情况下Bokeh)允许提供数百万个点。
服务器端渲染:Datashader或Vaex的外部外部InfoVis服务器端呈现通过将任意大的分布式或非核心数据集转换为固定大小的图像嵌入客户端浏览器,允许web浏览器中的数十亿、数万亿或更多数据点。
由于这些类型的库支持的数据大小范围很广(从而在某种程度上支持数据类型),需要处理大数据的用户需要在一开始就选择合适的库。
用户界面及发布
不同的库在使用绘图的方式上有很大的不同。
静态图像:大多数库现在可以轻松地创建静态图像,至少在PNG中是这样,通常在SVG或PDF等平滑矢量格式中也是如此。
本地GUI应用程序:SciVis库加上Matplotlib和Vaex可以创建特定操作系统的GUI窗口,这些窗口可以提供高性能,支持大型数据集以及与其他桌面应用程序的集成,但是它们绑定在特定的操作系统上,通常需要在本地运行而并非在网络上。在某些情况下,基于javascript的工具也可以通过嵌入网络浏览器嵌入到本地应用程序当中。
导出到HTML:大多数JavaScript和JSON库都可以在无服务器模式下运行,该模式生成交互式绘图(缩放、平移等),可以通过电子邮件发布在web服务器上,而不需要Python。
Jupyter记事本:大多数InfoVis库现在都支持在Jupyter记事本中进行交互式使用,并且Python支持基于JavaScript的绘图。基于ipywidgets的项目提供了与Jupyter更紧密的集成,而其他一些方法只提供了Jupyter中有限的交互性(例如,与Matplotlib而不是Bokeh一起使用全息视图)。
独立的基于Web的仪表板和应用程序:Plotly图表可以用在带有Dash的单独可部署应用程序中,而Bokeh,HoloViews以及geoview可以使用Bokeh服务器部署。大多数其他的InfoVis库可以使用新的Panel库作为仪表板部署,至少包括Matplotlib、Altair、Plotly、Datashader、hvPlot、Seaborn、plotnine和yt。然而,尽管基于web的交互性很好,但是基于ipywidgets的库(ipyleaflet,pythreejs,ipyvolume,bqplot)作为面向公众的应用程序很难部署,因为Jupyter服务器允许任意代码执行(但是请参阅失效的Jupyter指示版项目和flask-ipywidgets来寻找潜在的解决方案)。
因此,用户需要考虑给定的库是否涵盖了他们期望的可视化使用范围。
API 类型
各种InfoVis库提供了大量的编程接口,适用于不同类型的用户以及创建可视化的不同方式。这些API在需要多少代码来完成常见任务以及它们为用户处理不常见任务和将基元组成新类型图表时提供多少控件方面有所不同:
面向对象的Matplotlib API :对于一些常见的任务,例如创建子数据Matplotlib的主API,允许完全控制和合成,但是复杂且高度冗长。
命令式Pyplot API:Matplotlib的基本界面允许使用Matplotlib风格的命令式命令,这些命令对简单的情况而言非常简洁,但并不是组合的。因此,很大程度上只支持一组特定的选项。
Imperative Pandas.plot APIs:以数据框架为中心,用户将主要在Pandas中准备数据,然后选择一个子集进行绘图。正如本系列的下一篇文章中讨论的那样,现在广泛的图表库和其它数据结构都支持它们,这使它们成为一组广泛支持的基本绘图命令。不是直接组合,但是可以从底层绘图库返回可组合对象(对于hvPlot)。
声明性图形API:The Grammar of Graphics-inspired 库如ggplot,plotnine,Altair和Bokeh(在某种程度上)提供了一种自然的方式来组合图形原语(如轴和符号),以创建完整的图形。
声明性数据API:基于其他库的本地API的基础上,HoloViews和GeoViews提供了一个更高级别的声明性和组合性API,专注于注释、描述和处理可视化数据,而不是绘制元素。
这些API都适合于具有不同背景和目标的用户,使得一些任务简单明了,而另一些则更加困难。除了Matplotlib之外,大多数库支持一个或最多两个可选API,因此选择一个适合每个用户的技术背景和首选工作流程的库非常重要。
新兴趋势
正如您所见,Python提供了大量可视化功能,其方法和重点的多样性体现在大量的可用的库中。方法之间的差异仍然十分重要,并且具有深远的影响,这意味着用户在对任何一种特别的方法进行深度探究之前都需要考虑到这些差异。但是正如我们在SciPy2018特别会议上看到的那样,融合趋势有助于降低用户选择库的重要性。了解更多有关新型趋势的信息,请继续关注本系列的第2部分,Python数据可视化2018:走向融合。
英文原文:https://www.anaconda.com/blog/developer-blog/python-data-visualization-2018-why-so-many-libraries/
译者:Lyx