声明式与命令式绘图

原文:towardsdatascience.com/declarative-vs-imperative-plotting-3ee9952d6bf3

快速成功数据科学

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/84ec83f4fe09146b62b3930d83666194.png

德尼拉多与命令式想象为国王的莱昂纳多绝对现实 _v16

如果你正在学习 Python,预计你将使用Matplotlib制作你的第一个绘图。Matplotlib 非常受欢迎,它是一个命令式绘图库。这意味着它使用逐步方法生成图形,这对于初学者来说很容易理解。

Python 还支持声明式绘图库,如seabornAltairHoloViews,这些库让你专注于应该显示什么,而不是如何绘制它。引用 Altair 文档,“关键思想是你在声明数据列视觉编码通道之间的链接,例如 x 轴、y 轴和颜色。其余的绘图细节将自动处理。基于这个声明式系统,从简单到复杂,可以创建一系列的绘图,使用简洁的语法。”

科学家和工程师可能会发现声明式方法很有吸引力,因为它可以使他们有更多时间做真正的工作,而不是编码。正如我经常说的,“科学第一,编码第二!”

在这篇快速成功数据科学文章中,我们将探讨命令式和声明式绘图。然而,主要焦点将是声明式风格,使用来自 seaborn、Plotly Expresshvplot的示例。


声明式与命令式:全景图

在我们深入细节之前,这里有一些两个绘图方法的主要观点、优点和弱点。

命令式绘图

Python 中的命令式绘图采用一种逐步的方法,用户明确地在相当低的级别上指定绘图的细节。用户可以直接控制绘图的每个元素,从而实现高度细粒度的定制。因此,与声明式方法相比,命令式绘图需要更多的手动干预,但可以生成更复杂的可视化效果。

在命令式绘图中的优点包括:

  • 对绘图细节的完全控制

  • 逐步方法易于理解

在命令式绘图中的弱点包括:

  • 可能需要许多行代码,使得程序复杂且难以阅读和维护。

  • 用户需要熟悉 API 细节,这导致了一个陡峭的学习曲线

  • 尝试不同的绘图配置和样式可能会很繁琐,因为每个都需要手动定制。

Matplotlib 是最受欢迎的命令式库,并包含一些声明式组件。此外,seaborn 库包装 Matplotlib,允许更广泛地使用声明式绘图。因此,对我来说,Matplotlib 只是“准命令式”。

同样,其他库——尽管被认为是声明式的——通常有一个基础实现,允许大量定制(准命令式),以及一个高级、更用户友好的 __ 接口,具有有限的定制(准声明式)。例如,PlotlyPlotly Express,而 HoloViews 有hvplot

声明式绘图

Python 中的声明式绘图围绕一个高级、表达性语法展开,允许用户使用简洁的语法描述他们想要的可视化。构建图表的大部分细节都被抽象化。用户声明他们想要的元素,绘图库则负责底层的实现。

声明式绘图库通常面向数据集。大多数都是为与pandas DataFrames(Python 对 Excel 电子表格的回应)良好协作而设计的。

声明式绘图具有几个显著的优点,包括:

  • 简洁、表达性强直观的语法,便于使用。

  • 一致性可重复性,得益于语法和逻辑的统一性,这也有助于减少编码错误。

  • 交互性可扩展性,用户利用底层库和框架处理图表的渲染、交互性和性能。

  • 适用于快速探索性数据分析图表的出色适用性,无需进行大量精炼即可用于发布。


代码示例

为了对各种库进行一致的评价,我们将使用相同的数据库并制作散点图。然后我们将拟合回归线到数据上,并添加标题和图例。所有示例都是在 JupyterLab 中构建的。

安装库

我们将使用以下开源库:pandasNumPyMatplotlibseabornPlotlyhvplotstatsmodels。您可以在每个先前的超链接中找到安装说明。我建议在虚拟环境中安装这些库,或者如果您是 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)

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/2e19e0357ab2ca67d5fcf609711a64e1.png

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']);

这是输出:

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/1695c735df420de5cdbd761ca67ff51b.png

使用 Matplotlib 构建的散点图(作者)

这里需要注意的一点是,你使用了 scatter() 方法,并且使用了 DataFrame 作为 x 轴和 y 轴:

ax.scatter(x=tips['total_bill'], y=tips['tip'])

这种方法是一种 声明式 方法,但它生成的图表如此 简单,以至于几乎任何目的都需要进一步的装饰,包括快速而粗糙的数据探索分析:

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/3c4dbd31ffc3f67dbdb508c254d3e58c.png

Matplotlib **ax.scatter()** 方法的输出(作者)

注意到没有 x 和 y 标签使得图表实际上变得毫无用处。因此,这不仅仅是一个独立的解决方案,这种声明式绘图方法只是更大(命令式)旅程中的一步。

下面列出了一些更有用的 Matplotlib 绘图方法。虽然这些图表一开始看起来“稀疏”,但 Matplotlib 提供了对细节的完全控制,使它们适合那些定制是重点的场景。

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/9150b5a653e0d4bb14b4f172cc69b89b.png

有用的 Matplotlib 绘图方法(来自 Python Tools for Scientists

Matplotlib 还提供了一个稍微简化了的方法来使用其 pyplot 模块制作相同的图表(参见 Demystifying Matplotlib)。以下是列表和语法:

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/ba62f2c5a2be87b12fa0e55ff5725deb.png

有用的 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');

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/f6c12df910f8261761e66db74f01502e.png

使用 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']);

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/e6ddb6fef38e6de321a9345f281c2ad7.png

使用 seaborn 更新后的散点图(作者制作)

regplot() 方法使用额外的参数,您可以在这里看到。其他 seaborn 图表类型列在下文。有关这些和其他方法的详细信息,请参阅 seaborn 文档

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/b59d55ef572e7a6a6948d1e219b42231.png

一些有用的 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

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/1450c04b8d06b2442a2efaa593b5d040.png

使用 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

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/425a27da00ea23ea4edf27d1b5f469e1.png

使用 Plotly Express 更新构建的散点图(作者)

Plotly Express 支持交互式图表,包括平移、缩放、悬停和可点击/可选图例。

下面是所有 Plotly Express 绘图方法的列表。详细信息请参阅文档

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/33d1c51bc4fa9669053483ea74421b8b.png

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)

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/c898af6d974a15868e73686837006800.png

使用 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

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/c6bf4149cb5b20df8756b36d2af66707.png

使用 hvplot 构建的更新散点图(作者)

这段代码比之前的示例更冗长。然而,有趣的是,hvplot 使用特殊运算符来简化叠加图表或并排显示图表的过程。

星号 (*) 叠加 图表,例如上面显示的回归线和散点图。加号 (+) 将它们 并排 放置。只需将以下代码行更改为如下所示:

# Overlay the scatter plot and regression line
scatter_with_regression = scatter + line

现在,散点图和回归线在单独的图表中显示:

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/cf2d8a3d8a03d2a720c7aae7e072aa0e.png

散点图和回归线并排显示(作者)

虽然将回归线添加到图例做了一些工作,但在 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)

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/9f9c77c0f8f88dd7e345d796e1b6c693.png

带有图例的散点图(作者)

hvplot 可用的绘图类型列在下面。更多详细信息请参阅用户指南

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/a263e6e2a2a52962b1100d3549719bae.png

一些有用的 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 轴的列名、标题以及回归线的颜色。这是结果:

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/ad182876618c8e9ada47fc2abbc861f4.png

使用自定义函数构建的 seaborn RegPlot(作者提供)

你可以使用这种定制方法与其他绘图库一起使用。


摘要

命令式绘图在 Python 中涉及一种逐步的方法,用户明确地指定图表的细节,处于相当低级别。当构建需要高度定制的复杂图表时,命令式库,如 Matplotlib,非常有用。

声明式绘图在 Python 中围绕高级方法,这些方法允许用户仅用几行代码就创建基本可视化。仍然允许进行不同程度的定制。

主要的绘图库都附带高级声明式组件。Matplotlib 有 seaborn,Plotly 有 Plotly Express,而 HoloViews 有 hvplot。

如 Anaconda 的 James Bednar 所指出的,声明式产品如 HoloViews 的最终目标是支持科学研究的整个生命周期,从初步探索到发表,再到工作的复制和新扩展。因此,声明式风格是 Python 统一、一致和前瞻性绘图解决方案的途径。


感谢!

感谢阅读,并关注我,未来将有更多快速成功数据科学项目。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值