作者提供的Goofy图片
足球迷有个让人讨厌的习惯。每当一位年轻但显然非凡的球员崭露头角时,他们就会将他与像梅西或罗纳尔多这样的传奇人物相比较。他们选择忘记这些传奇人物在新手长出牙齿之前就已经统治了比赛。从某种意义上讲,将Plotly与Matplotlib进行比较,在一开始也是类似的。
Matplotlib自2003年以来一直被广泛使用,而Plotly在2014年才问世。
许多人在这个时候已经对Matplotlib感到厌倦,因此Plotly因其新鲜和互动性而受到热烈欢迎。然而,这个库无法希望从Matplotlib夺走Python绘图包的头把交椅。
2019年,Plotly在7月份发布了其Express API,这引发了对该库的极大兴趣,人们开始左右使用它。
去年6月发布了另一个重大版本(5.0.0),我认为Plotly已经足够成熟,可以与Matplotlib进行比较。
话虽如此,让我们开始吧:
自定义函数以绘制分数。完整的函数体可以在我创建的这个GitHub Gist中查看。
1. API的易用性
让我们首先比较它们的API的易用性。它们都提供高级和低级接口来与核心功能进行交互。
1.1 高级API(Pyplot vs. Express)的一致性
一方面,Plotly Express在一致性方面表现出色。它仅包含访问内置绘图的高级函数。它不引入执行现有功能的新方法-它是一个包装器。对Express的所有绘图调用都返回核心Figure对象。
另一方面,PyPlot接口将所有绘图函数和自定义函数打包到一个新的API中。即使绘图调用具有相同的签名,自定义函数也不同于Matplotlib的面向对象API中的自定义函数。
这意味着如果你想切换接口,你必须花费时间学习它们之间的差异。
此外,在Matplotlib中,创建绘图在底层返回不同的对象。例如,plt.scatter
返回一个PathCollection
对象,而plt.boxplot
返回一个字典。这是因为Matplotlib为每种绘图类型实现了不同的基类。这对许多人来说可能会非常令人困惑。
1.2 切换API所需的代码量
要从Matplotlib的PyPlot切换到其面向对象的API,你只需更改与核心数据结构(如figure
和axes
对象)交互的方式。绘图调用具有类似的签名,参数名称不会改变。
从Plotly Express切换到Plotly Graph Objects(GO)需要一个陡峭的学习曲线。创建所有绘图的函数签名都会改变,并且GO在每个绘图调用中添加了更多的参数。即使这样做是为了引入更多的自定义,我认为绘图最终变得异常复杂。
另一个缺点是GO将一些核心参数移出了绘图调用。例如,在Plotly Express中可以直接在绘图中创建对数坐标轴。在GO中,你可以使用update_layout
或update_axes
函数来实现这一点。在Matplotlib的PyPlot或面向对象API中不是这样的(参数不会移动或更改名称)。
1.3 自定义API
尽管有一个单独的自定义部分,我们必须从API的角度来谈论它。
在Matplotlib中,所有自定义都有单独的函数。这使你可以将代码块更改为更改绘图,并使用循环或其他过程。
相比之下,Plotly广泛使用字典。虽然这为你与绘图和数据的交互提供了一定的一致性,但它的代价是代码的可读性和长度。由于许多人喜欢update_layout
函数,它的参数经常以嵌套字典的森林结束。
你可能会停下来思考这些API之间的差异,但Matplotlib的API更具有Python风格和可读性。
2. 速度
为了看到速度的真正差异,我们必须使用更大的数据集。我将从Seaborn导入钻石数据集,并比较创建简单散点图所需的时间。
我将使用%%timeit
魔法命令,它会运行相同的代码块多次以查看标准偏差误差。
测量Matplotlib:
测量Plotly:
Matplotlib几乎比Plotly快80倍,并具有较低的SD误差。也许这是因为Plotly呈现交互式绘图。让我们再次检查速度,这次关闭交互:
不幸的是,关闭交互并没有什么帮助。Matplotlib在速度方面压倒Plotly:
# 3. 支持的图表类型数量
在这方面,Plotly 领先。从 Plotly 的 API 参考文档中,我数了近 50 种独特的图表类型。特别是当涉及到某些类型的图表时,Plotly 的表现非常出色。
例如,它专门支持金融绘图,并提供了 figure_factory
子包来创建更复杂、自定义的图表。
另一方面,Matplotlib 的图表种类比较有限。即使我们添加 Seaborn 的图表类型,我认为它们也无法与 Plotly 提供的丰富选择相匹配。
plot_scores(3, 2)
4. 交互性
如果只有 Plotly 具有此功能,我们如何比较交互性呢?
其实很少有人知道,在 Jupyter Notebook 之外,Matplotlib 的图表默认情况下会以交互模式渲染。
作者截图
不幸的是,这种交互性远不及 Plotly。因此,我们让 Plotly 的得分再加一分:
plot_scores(3, 3)
现在,为了分出胜负——除了一般的交互性之外,Plotly 还提供了自定义按钮:
滑块:
以及许多其他功能,将整个用户体验提升到了一个新的水平。这值得再加一分:
plot_scores(3, 4)
5. 自定义
对于许多数据科学家来说,自定义是至关重要的。你可能想根据项目的数据创建自定义主题并使用品牌颜色(可以在这里看到可视化 Netflix 数据的一个很好的例子)。
有了这些,让我们看看你可以调整的最重要的组件以及这些包之间的区别。
5.1 颜色和调色板
Matplotlib 和 Plotly 都有专门的子模块用于颜色和调色板。
Matplotlib 允许用户使用颜色标签、十六进制代码、RGB 和 RGBA 系统更改绘图元素的颜色。最值得注意的是,在 mpl.colors.CSS4_COLORS
下,你可以传递超过 100 个 CSS 颜色标签。
Plotly 确实实现了相同的功能,但 Matplotlib 提供了来自其他绘图软件(如 Tableau)的颜色。此外,在 Matplotlib 中传递颜色和调色板不会太混乱。
在 Plotly 中,有不少于六个处理不同调色板的参数。相比之下,MPL 只有两个灵活的参数 color
和 cmap
,可以适应你传递的任何颜色系统或调色板。
plot_scores(4, 4)
5.2 默认样式
在日常分析中,没有必要超越默认设置。这些类型的分析通常会持续很长时间,因此这些默认设置必须能够在短时间内生成尽可能高质量的图表。
我认为我们都可以同意 Matplotlib 的默认设置,呃,很糟糕。看看以下两个库创建的奥运会运动员身高和体重的散点图:
Plotly 的看起来更好。
此外,我喜欢 Plotly 遵循数据可视化最佳实践的方式,例如仅在必要时使用额外颜色。
例如,在创建条形图或箱线图时,Plotly 使用统一颜色而不是调色板。Matplotlib 则相反——它为每个条形图或箱线图上色,即使颜色不会向图表添加新信息。
plot_scores(4, 5)
5.3 主题
Plotly 之所以在这个部分独占鳌头,是因为它拥有绝妙的“暗模式”(叫我主观,我不在意)。它更加舒适,并且给图表带来了奢华的感觉(特别是当它与我最喜欢的红色一起使用时):
在 Jupyter Lab 中它看起来非常流畅!
plot_scores(4, 6)
5.4 全局设置
我需要花费很长时间才能将其集成到 Plotly 中的原因是其缺乏控制全局设置的功能。
Matplotlib 有 rcParams
字典,你可以轻松地调整它以全局设置绘图选项。你可能认为一个严重依赖于字典的库会有一个类似的字典,但实际上没有!
在这方面,Plotly 让我非常失望。
plot_scores(5, 6)
5.5 坐标轴
坐标轴最重要的组件是刻度标记和刻度标签。
说实话,直到今天,我仍然不完全掌握在 Matplotlib 中控制刻度的方法。这是因为 Matplotlib 没有一个一致的 API 用于控制坐标轴。
你可以责怪我没有努力尝试,但我通过查看文档一次性解决了 Plotly 中有关控制刻度的所有问题。
Plotly有一种处理刻度的方式(通过update_xaxes/update_yaxes
或update_layout
),在Express和GO之间切换时这些函数不会改变,而在Matplotlib中则不是这样。
plot_scores(5, 7)
5.6 控制图表的单个方面怎么样?
这个问题我们要把它交给Matplotlib。我这样做并不是因为Plotly已经领先了,而是我必须保持紧张刺激的感觉。
Matplotlib将单个组件实现为单独的类,使其API非常细粒度。更细粒度意味着更多的选项来控制图表上可见的对象。
以箱线图为例:
即使图表看起来空白,它也允许几乎无限的定制。例如,在返回的字典的boxes
键下,你可以访问每个箱线图作为Patch对象:
这些对象打开了Matplotlib底层魔法的大门。它们不仅限于箱线图,你还可以从许多其他图表中访问Patch对象。使用这些patch对象,你可以自定义图形中形状周围的每条线、每个角和每个点。
plot_scores(6, 7)
6. 散点图
散点图在统计分析中起着重要作用。
它们用于理解相关性和因果关系,检测异常值并在线性回归中绘制最佳拟合线。因此,我决定专门比较两个库的散点图。
为此,我将从前面的部分选择身高与体重的散点图:
Matplotlib的默认散点图。
我知道,看起来很恶心。然而,看看我执行一些自定义操作,将图表变成了一件(好吧,我不会说艺术品):
减小刻度的大小并使它们不那么不透明后的相同散点图
在应用最后一步之前,我们可以看到点分组在不同的行和列周围。让我们添加jittering并看看会发生什么:
jittering后的相同散点图。
现在将初始图与最终图进行比较:
左-初始图。右-变换后。
在Plotly中,我们甚至不知道点是如何分组为行和列的。它不允许将标记大小更改为小于默认值。
这意味着我们无法将分布抖动以解决体重和身高被离散值舍入的事实。
plot_scores(7, 7)
哇!直到这一点,它们一直都很接近。
7. 文档
作为最后一个组成部分和决定胜负的关键,让我们比较一下文档。
当我是初学者时,Matplotlib文档是我最不希望找到答案的地方。
首先,你无法在打开几个其他链接的情况下阅读文档的单个页面。文档是一个混乱的怪物。
其次,它的教程和示例脚本似乎是为学术研究人员编写的,几乎就像Matplotlib试图故意吓唬初学者一样。
相比之下,Plotly要更加有组织。它有完整的API参考,并且其教程大多是独立的。
它不是完美的,但至少看起来很好看-它不会让你感觉像在阅读90年代的报纸页面。
plot_scores(7, 8)
> 2022年更新:Matplotlib彻底改版了其文档,它看起来非常令人愉快。我们可以将此部分称为平局。
总结
说实话,我写这篇比较时完全确信Matplotlib会赢。
到一半时,我知道情况将会相反,而且我是正确的。
Plotly真的是一个非常出色的库。即使我让个人偏好和偏见影响了得分,但没有人可以否认该软件包已经取得了许多里程碑,并且仍在快速发展。
本文的目的不是说服你放弃一个软件包并使用另一个软件包。相反,我想突出每个软件包擅长的领域,并展示如果将两个库添加到你的工具包中,你可以创建什么。
谢谢你的阅读!
译自:https://towardsdatascience.com/matplotlib-vs-plotly-lets-decide-once-and-for-all-dc3eca9aa011
评论(0)