原文:
towardsdatascience.com/declarative-vs-imperative-plotting-3ee9952d6bf3
快速成功数据科学
德尼拉多与命令式想象为国王的莱昂纳多绝对现实 _v16
如果你正在学习 Python,预计你将使用Matplotlib制作你的第一个绘图。Matplotlib 非常受欢迎,它是一个命令式绘图库。这意味着它使用逐步方法生成图形,这对于初学者来说很容易理解。
Python 还支持声明式绘图库,如seaborn、Altair和HoloViews,这些库让你专注于应该显示什么,而不是如何绘制它。引用 Altair 文档,“关键思想是你在声明数据列和视觉编码通道之间的链接,例如 x 轴、y 轴和颜色。其余的绘图细节将自动处理。基于这个声明式系统,从简单到复杂,可以创建一系列的绘图,使用简洁的语法。”
科学家和工程师可能会发现声明式方法很有吸引力,因为它可以使他们有更多时间做真正的工作,而不是编码。正如我经常说的,“科学第一,编码第二!”
在这篇快速成功数据科学文章中,我们将探讨命令式和声明式绘图。然而,主要焦点将是声明式风格,使用来自 seaborn、Plotly Express和hvplot的示例。
声明式与命令式:全景图
在我们深入细节之前,这里有一些两个绘图方法的主要观点、优点和弱点。
命令式绘图
Python 中的命令式绘图采用一种逐步的方法,用户明确地在相当低的级别上指定绘图的细节。用户可以直接控制绘图的每个元素,从而实现高度细粒度的定制。因此,与声明式方法相比,命令式绘图需要更多的手动干预,但可以生成更复杂的可视化效果。
在命令式绘图中的优点包括:
-
对绘图细节的完全控制。
-
逐步方法易于理解。
在命令式绘图中的弱点包括:
-
可能需要许多行代码,使得程序复杂且难以阅读和维护。
-
用户需要熟悉 API 细节,这导致了一个陡峭的学习曲线。
-
尝试不同的绘图配置和样式可能会很繁琐,因为每个都需要手动定制。
Matplotlib 是最受欢迎的命令式库,并包含一些声明式组件。此外,seaborn 库包装 Matplotlib,允许更广泛地使用声明式绘图。因此,对我来说,Matplotlib 只是“准命令式”。
同样,其他库——尽管被认为是声明式的——通常有一个基础实现,允许大量定制(准命令式),以及一个高级、更用户友好的 __ 接口,具有有限的定制(准声明式)。例如,Plotly有Plotly Express,而 HoloViews 有hvplot。
声明式绘图
Python 中的声明式绘图围绕一个高级、表达性语法展开,允许用户使用简洁的语法描述他们想要的可视化。构建图表的大部分细节都被抽象化。用户声明他们想要的元素,绘图库则负责底层的实现。
声明式绘图库通常面向数据集。大多数都是为与pandas DataFrames(Python 对 Excel 电子表格的回应)良好协作而设计的。
声明式绘图具有几个显著的优点,包括:
-
简洁、表达性强和直观的语法,便于使用。
-
一致性和可重复性,得益于语法和逻辑的统一性,这也有助于减少编码错误。
-
交互性和可扩展性,用户利用底层库和框架处理图表的渲染、交互性和性能。
-
适用于快速探索性数据分析图表的出色适用性,无需进行大量精炼即可用于发布。
代码示例
为了对各种库进行一致的评价,我们将使用相同的数据库并制作散点图。然后我们将拟合回归线到数据上,并添加标题和图例。所有示例都是在 JupyterLab 中构建的。
安装库
我们将使用以下开源库:pandas、NumPy、Matplotlib、seaborn、Plotly、hvplot和statsmodels。您可以在每个先前的超链接中找到安装说明。我建议在虚拟环境中安装这些库,或者如果您是 Anaconda用户,则在 conda 环境中安装。
当在 Jupyter Notebook 或 JupyterLab 中使用 Plotly Express 时,你可能会被要求安装 nbformat。你可以在命令行界面使用以下任一方法来完成此操作:
pip install nb format
或
conda install -c conda-forge nbformat
加载数据
对于数据,我们将使用 Seaborn 附带的数据集 tips。这个数据集记录了餐厅数据,如总账单、小费金额、星期几、聚会规模等。以下是加载它的方法:
import seaborn as sns
# Load the tips dataset:
tips = sns.load_dataset('tips')
数据以 pandas DataFrame 的形式加载。以下是前三行:
tips.head(3)
tips DataFrame 的头部(作者)
Matplotlib – 命令式示例
让我们从命令式库 Matplotlib 开始。注意我们如何需要构建一个图形(fig)和坐标轴(ax)对象,创建散点图,构建并添加回归线,以及手动设置标签、标题和图例。
# Matplotlib imperative example:
import numpy as np
import matplotlib.pyplot as plt
# Create a figure and axes:
fig, ax = plt.subplots()
# Plot the data:
ax.scatter(x=tips['total_bill'], y=tips['tip'])
# Fit and plot a linear regression line:
m, b = np.polyfit(x=tips['total_bill'], y=tips['tip'], deg=1)
ax.plot(tips['total_bill'], m*tips['total_bill'] + b, color='red')
# Set the labels, title, and legend:
ax.set_xlabel('Total bill')
ax.set_ylabel('Tip')
ax.set_title('Imperative Example - Matplotlib (fig, ax)')
ax.legend(['Data', 'Linear fit']);
这是输出:
使用 Matplotlib 构建的散点图(作者)
这里需要注意的一点是,你使用了 scatter() 方法,并且使用了 DataFrame 列 作为 x 轴和 y 轴:
ax.scatter(x=tips['total_bill'], y=tips['tip'])
这种方法是一种 声明式 方法,但它生成的图表如此 简单,以至于几乎任何目的都需要进一步的装饰,包括快速而粗糙的数据探索分析:
Matplotlib **ax.scatter()** 方法的输出(作者)
注意到没有 x 和 y 标签使得图表实际上变得毫无用处。因此,这不仅仅是一个独立的解决方案,这种声明式绘图方法只是更大(命令式)旅程中的一步。
下面列出了一些更有用的 Matplotlib 绘图方法。虽然这些图表一开始看起来“稀疏”,但 Matplotlib 提供了对细节的完全控制,使它们适合那些定制是重点的场景。
有用的 Matplotlib 绘图方法(来自 Python Tools for Scientists)
Matplotlib 还提供了一个稍微简化了的方法来使用其 pyplot 模块制作相同的图表(参见 Demystifying Matplotlib)。以下是列表和语法:
有用的 Matplotlib pyplot 方法用于制作图表(来自 Python Tools for Scientists)
这些 pyplot 方法主要是为了制作 单个 图表。
Seaborn – Declarative Example
如前所述,seaborn 是一个声明式库,旨在创建比原生 Matplotlib 更简单、更吸引人的图表。以下是使用回归线创建散点图的代码:
# seaborn declarative example:
import matplotlib.pyplot as plt
import seaborn as sns
sns.regplot(data=tips, x='total_bill', y='tip');
使用 seaborn 构建的散点图(作者制作)
我们使用最后一行代码构建了这个图表。没有必要指定 x 轴和 y 轴的标签,也不需要构建回归。作为额外的好处,回归线带有 95% 置信区间阴影,标记是半透明的,突出了标记密度的变化。
回归线的 95% 置信区间是一种统计量度,它提供了一个范围,在这个范围内,真正的回归线合理地预期会落在其中。
如果图表带有标题和图例那就更好了。我假设这些被省略了,以免“妨碍”快速探索性数据分析。尽管如此,这还是有点令人失望。
但不必担心,我们可以通过一些额外的代码添加这些功能,以便我们的 seaborn 图表与使用 Matplotlib 生成的图表相匹配。
# Recolor regression line and add a legend:
sns.regplot(data=tips,
x='total_bill', y='tip',
line_kws={'label': 'Linear Fit',
'color': 'red'})
plt.title('Declarative Example - Seaborn')
plt.legend(labels=['Data', 'Linear Fit']);
使用 seaborn 更新后的散点图(作者制作)
regplot() 方法使用额外的参数,您可以在这里看到。其他 seaborn 图表类型列在下文。有关这些和其他方法的详细信息,请参阅 seaborn 文档。
一些有用的 seaborn 绘图方法(来自 Python Tools for Scientists)
Plotly Express – 声明式示例
Plotly Express 是 Plotly 图形库的内置部分。作为 Plotly 的一个更简单、更高级的版本,它是创建常见图形的推荐起点。
Plotly Express 包含超过 30 个函数,可以一次性创建整个图表,这些函数的 API 被精心设计,以尽可能保持一致性和易于学习。这使得在数据探索会话中轻松切换图表类型变得容易。
这里是生成带有回归线的散点图的 Plotly Express 代码:
# Plotly Express declarative example:
import plotly.express as px
fig = px.scatter(tips, x='total_bill', y='tip',
trendline='ols',
trendline_color_override='red',
title='Declarative Example - Plotly Express',
width=700, height=500)
fig
使用 Plotly Express 构建的散点图(作者制作)
注意我们如何能够通过 [px.scatter()](https://plotly.com/python-api-reference/generated/plotly.express.scatter) 方法中的参数添加标题和回归线(“ols”代表“普通最小二乘法”)。后者是通过 [statsmodels](https://www.statsmodels.org/stable/index.html) 库实现的。
px.scatter() 方法还允许通过 color 参数使用图例,该参数引用 DataFrame 列,例如:
color='smoker'
然而,这里我们想要将 回归线 添加到图例中,这需要额外的代码:
# Add a red regression line:
fig = px.scatter(tips,
x='total_bill', y='tip',
trendline='ols',
title='Declarativpe Example - Plotly Express',
trendline_color_override='red',
width=700, height=500)
# Add a legend entry for the regression line
fig.data[0].name = 'Data'
fig.data[0].showlegend = True
fig.data[1].name = fig.data[1].name + 'Linear Fit'
fig.data[1].showlegend = True
fig
使用 Plotly Express 更新构建的散点图(作者)
Plotly Express 支持交互式图表,包括平移、缩放、悬停和可点击/可选图例。
下面是所有 Plotly Express 绘图方法的列表。详细信息请参阅文档。
Plotly Express 图表类型(作者来自官方文档)
hvplot – 声明式示例
hvplot 库是 HoloViews 绘图库的高级声明式接口。它旨在通过最少的代码简化创建复杂可视化的过程。它与 pandas DataFrame 无缝工作,使用户能够直接从其数据结构中可视化数据。
作为 HoloViz 生态系统的一部分,它与 Panel、Bokeh 和 GeoViews 等工具无缝集成,以生成仪表板和其他交互式可视化。其基于 Bokeh 的 API 支持平移、缩放、悬停和可点击/可选图例。
下面是生成散点图的 hvplot 代码:
# hvplot declarative example:
import numpy as np
import pandas as pd
import hvplot.pandas
tips.hvplot.scatter(x='total_bill', y='tip',
title='Declarative Example - hvplot',
width=700,
height=500)
使用 hvplot 构建的散点图(作者)
现在,让我们添加回归线和图例:
# Add a regression line and legend:
scatter = tips.hvplot.scatter(x='total_bill', y='tip',
title='Declarative Example - hvplot',
label='Data',
width=800, height=500)
# Calculate linear regression coefficients
m, b = np.polyfit(tips['total_bill'], tips['tip'], deg=1)
# Create a line using the regression coefficients
line = pd.DataFrame({'total_bill': [tips['total_bill'].min(),
tips['total_bill'].max()],
'tip': [m * tips['total_bill'].min() + b,
m * tips['total_bill'].max() + b]})
# Line plot using hvplot
regression_line = line.hvplot.line(x='total_bill', y='tip',
color='red',
label='Linear Fit')
# Overlay the scatter plot and regression line
scatter_with_regression = scatter * regression_line
scatter_with_regression
使用 hvplot 构建的更新散点图(作者)
这段代码比之前的示例更冗长。然而,有趣的是,hvplot 使用特殊运算符来简化叠加图表或并排显示图表的过程。
星号 (*) 叠加 图表,例如上面显示的回归线和散点图。加号 (+) 将它们 并排 放置。只需将以下代码行更改为如下所示:
# Overlay the scatter plot and regression line
scatter_with_regression = scatter + line
现在,散点图和回归线在单独的图表中显示:
散点图和回归线并排显示(作者)
虽然将回归线添加到图例做了一些工作,但在 hvplot 中通常图例很容易。您只需指定一个类别,例如 DataFrame 列,作为标记颜色的依据。以下是一个使用 “smoker” 列作为 by 参数的示例:
# Add the legend using the scatter() method:
import numpy as np
import pandas as pd
import hvplot.pandas
tips.hvplot.scatter(x='total_bill', y='tip',
by='smoker',
title='Declarative Example - hvplot',
label='Data',
legend='top_right',
width=700,
height=500)
带有图例的散点图(作者)
hvplot 可用的绘图类型列在下面。更多详细信息请参阅用户指南。
一些有用的 hvplot 方法(作者来自官方文档)
定制声明式方法
我发现这让人沮丧——而且有点令人困惑——我们在这篇文章中回顾的声明式方法默认不生成完整的图表。这里的“完整”是指包含必要元素的图表,例如:
-
标题
-
图例
-
标记和注释的 x 轴和 y 轴
-
背景网格
幸运的是,了解 Python 意味着你不必妥协。你可以生成自己的声明式函数来制作图表。现在我们就利用之前使用的 seaborn regplot() 方法来做这件事:
# Function for a "complete" seaborn regression plot:
def my_regplot(data, x, y, title, line_color):
"""Draw a seaborn regplot with title and legend."""
sns.set_style("whitegrid")
sns.regplot(data=data,
x=x, y=y,
label='Data',
line_kws={'label': 'Linear Fit (95% CI)',
'color': line_color})
plt.title(title)
plt.legend(loc='best')
#plt.savefig(f'{title}.png', dpi=400) # optional save
my_regplot(tips, 'total_bill', 'tip', 'My RegPlot Example', 'red')
此函数接受一些regplot()方法参数以及一个用于标题的参数。seaborn 的set_style方法添加背景网格,而 Matplotlib 的pyplot模块添加标题和图例。
当你调用函数时,你需要传递 DataFrame 的名称、用于 x 轴和 y 轴的列名、标题以及回归线的颜色。这是结果:
使用自定义函数构建的 seaborn RegPlot(作者提供)
你可以使用这种定制方法与其他绘图库一起使用。
摘要
命令式绘图在 Python 中涉及一种逐步的方法,用户明确地指定图表的细节,处于相当低级别。当构建需要高度定制的复杂图表时,命令式库,如 Matplotlib,非常有用。
声明式绘图在 Python 中围绕高级方法,这些方法允许用户仅用几行代码就创建基本可视化。仍然允许进行不同程度的定制。
主要的绘图库都附带高级声明式组件。Matplotlib 有 seaborn,Plotly 有 Plotly Express,而 HoloViews 有 hvplot。
如 Anaconda 的 James Bednar 所指出的,声明式产品如 HoloViews 的最终目标是支持科学研究的整个生命周期,从初步探索到发表,再到工作的复制和新扩展。因此,声明式风格是 Python 统一、一致和前瞻性绘图解决方案的途径。
感谢!
感谢阅读,并关注我,未来将有更多快速成功数据科学项目。
1150

被折叠的 条评论
为什么被折叠?



