第三章:Seaborn关系图 (Relational Plots) 第三章:Seaborn关系图 (Relational Plots) 详解与实践 Seaborn,作为Python数据可视化库中的佼佼者,构建于Matplotlib之上,专注于统计图形的绘制。它以其简洁的API和美观的默认样式,深受数据科学家和分析师的喜爱。Seaborn的核心理念之一是关系可视化,即通过图形来揭示数据集中变量之间的关系。而关系图 (Relational Plots) 正是Seaborn中用于展现这种关系的关键工具。 关系图 (Relational Plots) 的概念与意义 在数据分析和可视化中,理解变量之间的关系至关重要。关系图旨在通过视觉化的方式,帮助我们发现和理解数据集中不同变量之间的相互作用模式。
Seaborn,作为Python数据可视化库中的佼佼者,构建于Matplotlib之上,专注于统计图形的绘制。它以其简洁的API和美观的默认样式,深受数据科学家和分析师的喜爱。Seaborn的核心理念之一是关系可视化,即通过图形来揭示数据集中变量之间的关系。而关系图 (Relational Plots) 正是Seaborn中用于展现这种关系的关键工具。
在数据分析和可视化中,理解变量之间的关系至关重要。关系图旨在通过视觉化的方式,帮助我们发现和理解数据集中不同变量之间的相互作用模式。这些模式可能包括:
相关性 (Correlation):变量之间是否呈现正相关、负相关或不相关?
趋势 (Trend):一个变量如何随着另一个变量的变化而变化?
分组关系 (Grouping):某些变量是否根据其他变量的类别进行分组或区分?
分布差异 (Distribution Difference):不同组别的数据在某些变量上的分布是否存在差异?
Seaborn的关系图提供了强大的工具,能够通过颜色、大小、形状、线条样式等视觉元素,将多个变量的信息同时编码到一张图表中。这使得我们能够高效地探索多维数据,并从中提取有价值的见解。
relplot():关系图的统一入口relplot() 函数是Seaborn中用于创建关系图的figure-level接口。这意味着 relplot() 函数本身可以创建包含多个子图的复杂图形,并且能够方便地处理数据集中的分类变量。
relplot() 函数的核心思想在于,它并非直接绘制特定的图形类型(如散点图或线图),而是根据 kind 参数的设置,委托给更底层的函数来完成具体的绘图任务。kind 参数允许我们指定要绘制的关系图类型,目前 relplot() 支持两种主要的 kind 值:
kind="scatter":创建散点图,用于展示两个变量之间的关系,并可以使用颜色、大小和形状等视觉元素来编码第三个甚至第四个变量。
kind="line":创建线图,主要用于展示一个变量如何随着另一个变量(通常是连续变量或有序变量)的变化而变化,尤其适用于时间序列数据或趋势分析。
如果不指定 kind 参数,relplot() 默认会绘制散点图 (kind="scatter")。
relplot() 函数的主要参数:
relplot() 函数接受许多参数,其中一些参数是通用的,适用于所有类型的关系图,而另一些参数则更 specific 于特定的 kind 值。以下是一些常用的通用参数:
data: DataFrame, array, or list of arrays,输入的数据集。
x, y: 变量名或向量数据,指定 x 轴和 y 轴的数据。
hue: 变量名或向量数据,用于通过颜色维度对数据进行分组。
size: 变量名或向量数据,用于通过点的大小维度对数据进行分组。
style: 变量名或向量数据,用于通过点的形状或线的样式维度对数据进行分组。
col, row: 变量名或向量数据,用于创建列和行方向的小图 (facets),根据指定的变量对数据进行分组,并在不同的子图中绘制。
col_wrap: 整数,当使用 col 参数创建列小图时,指定每行最多显示的列数,用于控制小图的布局。
palette: 调色板名称、列表或字典,指定用于 hue 变量的颜色方案。
markers: 布尔值、列表或字典,指定散点图中点的标记样式,或线图中点的标记样式。
sizes: 列表或元组,或字典,指定 size 变量映射到点的大小的范围或具体大小。
legend: "auto", "brief", "full", or False,控制图例的显示方式。
Graph TD 图示 relplot() 的工作原理:
代码实践 1:使用 relplot() 创建基本的散点图
import seaborn as sns import matplotlib.pyplot as plt # 加载示例数据集 "tips" tips = sns.load_dataset("tips") # 使用 relplot() 创建散点图,展示 total_bill 和 tip 之间的关系 sns.relplot(data=tips, x="total_bill", y="tip") plt.title("Total Bill vs Tip (Basic Scatter Plot)") plt.show()
这段代码展示了 relplot() 最基本的使用方法。我们指定了数据集 tips,以及 x 轴变量 total_bill 和 y 轴变量 tip。relplot() 默认绘制散点图,清晰地展示了小费金额通常随着总账单金额的增加而增加的趋势。
scatterplot()): 探索变量间的关系散点图 (scatterplot()) 是关系图中最常用的一种类型,它通过在二维坐标系中绘制数据点的散布情况,来直观地展示两个数值变量之间的关系。每个点代表一个数据样本,点的横坐标和纵坐标分别对应两个变量的取值。
scatterplot() 函数是 relplot(kind="scatter") 的底层实现函数。 虽然可以直接使用 scatterplot() 函数,但通常推荐使用 relplot(),因为它提供了更统一的接口和更强大的功能,尤其是在处理分类变量和创建小图方面。
散点图的增强:视觉编码
散点图的强大之处在于,它可以通过多种视觉编码方式来展示更多维度的数据信息。Seaborn 提供了 hue, size, 和 style 参数,可以将分类变量的信息映射到散点图的颜色、大小和形状上。
hue 参数:颜色维度
hue 参数可以根据分类变量的不同取值,将散点图中的点着上不同的颜色。这可以帮助我们观察不同类别的数据在两个数值变量关系上的差异。代码实践 2:使用 hue 参数添加颜色维度
sns.relplot(data=tips, x="total_bill", y="tip", hue="sex") plt.title("Total Bill vs Tip, Colored by Sex") plt.show()
在这个例子中,我们添加了 hue="sex" 参数,将性别 (sex) 变量映射到颜色维度。散点图中的点根据顾客的性别被着上了不同的颜色 (默认颜色方案)。我们可以观察到,男性顾客和女性顾客在总账单和小费金额的关系上,似乎没有明显的差异,但通过颜色区分,我们可以更清晰地进行观察和比较。
size 参数:大小维度
size 参数可以将数值型或有序分类变量映射到散点图中点的大小。这可以用来表示第三个变量的量级,或者强调某些数据点的权重。代码实践 3:使用 size 参数添加大小维度
sns.relplot(data=tips, x="total_bill", y="tip", size="size") # 注意这里 "size" 是指餐桌人数 plt.title("Total Bill vs Tip, Sized by Party Size") plt.show()
这里我们使用 size="size" 参数,将餐桌人数 (size) 变量映射到点的大小。点的大小随着餐桌人数的增加而增大。我们可以观察到,餐桌人数较多的订单,其总账单金额和小费金额通常也较高。
style 参数:形状维度
style 参数可以将分类变量映射到散点图中点的形状。这在需要区分多个类别,或者颜色维度已经被占用时非常有用。代码实践 4:使用 style 参数添加形状维度
sns.relplot(data=tips, x="total_bill", y="tip", style="smoker") plt.title("Total Bill vs Tip, Styled by Smoker") plt.show()
这里我们使用 style="smoker" 参数,将是否吸烟 (smoker) 变量映射到点的形状。吸烟者和非吸烟者的点使用了不同的形状 (默认形状)。我们可以观察到,吸烟与否似乎对总账单和小费金额的关系没有显著影响。
同时使用 hue, size, style 参数
我们可以同时使用 hue, size, 和 style 参数,将多个分类或数值变量的信息编码到散点图中,从而创建更丰富、信息量更密集的图形。
代码实践 5:同时使用 hue, size, style 参数
sns.relplot(data=tips, x="total_bill", y="tip", hue="sex", size="size", style="smoker") plt.title("Total Bill vs Tip, Hue=Sex, Size=Party Size, Style=Smoker") plt.show()
在这个例子中,我们同时使用了 hue="sex", size="size", style="smoker",将性别、餐桌人数和是否吸烟三个变量的信息都编码到了散点图中。通过观察这个图形,我们可以同时考虑这三个因素对总账单和小费金额关系的影响。
Graph TD 图示 散点图的视觉编码:
scatterplot() 的其他重要参数:
markers: 用于自定义散点图中点的标记样式。可以传入一个列表,为 style 变量的每个类别指定不同的标记;也可以传入一个字典,将类别名称映射到特定的标记。
sizes: 用于自定义 size 变量映射到点的大小的范围。可以传入一个元组 (min_size, max_size),指定最小和最大点的大小;也可以传入一个字典,将 size 变量的具体取值映射到点的大小。
palette: 用于自定义 hue 变量的颜色方案。可以使用 Seaborn 内置的调色板名称,也可以传入自定义的颜色列表或字典。
代码实践 6:自定义散点图的标记和颜色
sns.relplot( data=tips, x="total_bill", y="tip", hue="day", style="time", palette="Set2", # 使用 Set2 调色板 markers=["o", "s", "^", "D"], # 自定义 day 变量的标记 ) plt.title("Scatter Plot with Custom Markers and Palette") plt.show()
这段代码演示了如何使用 palette 和 markers 参数来自定义散点图的颜色和标记。我们使用了 "Set2" 调色板,并为 day 变量的每个类别指定了不同的标记形状。
lineplot()): 探索趋势与变化线图 (lineplot()) 主要用于展示一个变量如何随着另一个变量的变化而变化,特别适用于展示趋势和时间序列数据。线图通过将数据点连接成线段,来强调变量之间的连续变化关系。
lineplot() 函数是 relplot(kind="line") 的底层实现函数。 同样地,推荐使用 relplot() 来创建线图,以便更好地利用其 figure-level 的特性。
线图的特点:趋势与估计
与散点图不同,线图更侧重于展示数据的趋势和变化模式,而不是单个数据点的精确位置。当数据存在一定的波动或噪声时,直接绘制所有数据点的线图可能会显得杂乱无章。为了更好地展示趋势,lineplot() 默认会对数据进行聚合和估计。
estimator 参数:中心趋势估计
estimator 参数用于指定用于估计中心趋势的函数。默认情况下,estimator 参数设置为 numpy.mean,即计算每个 x 值对应的 y 值的平均值。
除了平均值,还可以使用其他的估计函数,例如 numpy.median (中位数), numpy.sum (总和) 等。如果设置为 None,则不进行聚合估计,直接绘制所有数据点。
errorbar 参数:误差范围
errorbar 参数用于指定是否绘制误差范围,以及误差范围的类型。误差范围可以帮助我们了解估计值的不确定性。
常用的 errorbar 值包括:
"sd" (标准差):绘制标准差作为误差范围。
"se" (标准误差):绘制标准误差作为误差范围。
"ci" (置信区间):绘制置信区间作为误差范围 (默认值是 95% 置信区间)。
None:不绘制误差范围。
代码实践 7:使用 lineplot() 创建基本的线图
import numpy as np # 生成示例数据 x = np.arange(10) y = np.random.randn(10) + x # 添加随机噪声 # 使用 lineplot() 创建线图 sns.lineplot(x=x, y=y) plt.title("Basic Line Plot") plt.show()
这段代码创建了一个简单的线图,展示了 y 变量随着 x 变量变化的趋势。由于 y 中添加了随机噪声,线图呈现出一定的波动性,但总体趋势仍然是上升的。
代码实践 8:使用 estimator 和 errorbar 参数
sns.lineplot(data=tips, x="size", y="tip", estimator=np.mean, errorbar="sd") plt.title("Line Plot with Mean Estimator and Standard Deviation Error Bar") plt.show()
在这个例子中,我们使用 estimator=np.mean 和 errorbar="sd" 参数。lineplot() 会计算每个餐桌人数 (size) 对应的平均小费金额,并绘制线图。同时,它还会绘制标准差作为误差范围,以显示平均小费金额的波动程度。
线图的增强:分组与样式
与散点图类似,线图也可以使用 hue, size, 和 style 参数来展示更多维度的数据信息。
hue 参数:颜色分组
hue 参数可以将分类变量映射到线的颜色,从而比较不同组别数据的趋势差异。代码实践 9:使用 hue 参数进行分组线图
sns.lineplot(data=tips, x="size", y="tip", hue="sex") plt.title("Line Plot Grouped by Sex") plt.show()
这里我们使用 hue="sex" 参数,将性别变量映射到线的颜色。线图会分别绘制男性顾客和女性顾客的小费金额随餐桌人数变化的趋势。我们可以比较两组顾客在小费习惯上的差异。
style 参数:线条样式分组
style 参数可以将分类变量映射到线的样式 (例如实线、虚线、点线等)。当需要区分多个组别,或者颜色维度已经被占用时,线条样式分组非常有用。代码实践 10:使用 style 参数进行线条样式分组
sns.lineplot(data=tips, x="size", y="tip", style="smoker") plt.title("Line Plot Styled by Smoker") plt.show()
这里我们使用 style="smoker" 参数,将是否吸烟变量映射到线的样式。线图会分别使用不同的线条样式绘制吸烟者和非吸烟者的小费金额随餐桌人数变化的趋势。
markers 和 dashes 参数:标记和虚线样式
markers 参数可以控制是否在线图中显示数据点标记。
dashes 参数可以自定义线条的虚线样式。
Graph TD 图示 线图的组件:
lineplot() 的其他重要参数:
sort: 布尔值,控制是否在绘制线图之前对 x 轴数据进行排序。默认为 True,通常建议保持默认值,以确保线图的连线顺序正确。
err_style: 字符串,控制误差范围的样式,可以是 "band" (带状阴影,默认值) 或 "bars" (误差棒)。
col, row, col_wrap 参数创建小图 (Facets)relplot() 的一个强大功能是能够方便地创建小图 (facets),也称为条件图或网格图。通过 col, row, 和 col_wrap 参数,我们可以根据分类变量的不同取值,将数据分割成多个子集,并在不同的子图中分别绘制关系图。这可以帮助我们观察不同组别数据之间的关系差异。
col 参数:列方向小图
col 参数指定一个分类变量,relplot() 会根据该变量的不同取值,在列方向上创建多个子图。代码实践 11:使用 col 参数创建列方向小图
sns.relplot(data=tips, x="total_bill", y="tip", col="day") plt.suptitle("Total Bill vs Tip, Faceted by Day", y=1.02) # 添加总标题 plt.show()
这段代码使用 col="day" 参数,将数据集按照星期 (day) 分割成多个子集,并在列方向上创建了四个子图,分别展示了每天的总账单和小费金额关系。
row 参数:行方向小图
row 参数与 col 参数类似,但它会在行方向上创建小图。代码实践 12:使用 row 参数创建行方向小图
sns.relplot(data=tips, x="total_bill", y="tip", row="smoker") plt.suptitle("Total Bill vs Tip, Faceted by Smoker", y=1.02) # 添加总标题 plt.show()
这里使用 row="smoker" 参数,将数据集按照是否吸烟 (smoker) 分割成两个子集,并在行方向上创建了两个子图。
col_wrap 参数:列小图换行
col 参数创建列小图,并且类别数量较多时,可以使用 col_wrap 参数指定每行最多显示的列数,以便控制小图的布局,避免图形过宽。代码实践 13:使用 col_wrap 参数控制列小图布局
import pandas as pd # 创建一个包含更多类别的数据集 (例如,假设有更多天的用餐数据) days_extended = pd.Categorical(["Thur", "Fri", "Sat", "Sun", "Mon", "Tue", "Wed"] * 100, categories=["Mon", "Tue", "Wed", "Thur", "Fri", "Sat", "Sun"], ordered=True) tips_extended = tips.sample(n=700, replace=True) # 扩大数据集 tips_extended['day_extended'] = days_extended.sort_values().reset_index(drop=True) # 添加扩展后的 day 变量 sns.relplot(data=tips_extended, x="total_bill", y="tip", col="day_extended", col_wrap=4) # col_wrap=4,每行最多显示 4 列 plt.suptitle("Total Bill vs Tip, Faceted by Extended Day, col_wrap=4", y=1.02) plt.show()
在这个例子中,我们假设数据集包含了更多天的用餐数据,并使用 col="day_extended" 和 col_wrap=4 参数。relplot() 会创建按天分割的小图,并且每行最多显示 4 列,使得图形布局更加紧凑。
同时使用 col 和 row 参数:网格小图
可以同时使用 col 和 row 参数,创建网格状的小图,根据两个分类变量的组合对数据进行分割。
代码实践 14:同时使用 col 和 row 参数创建网格小图
sns.relplot(data=tips, x="total_bill", y="tip", col="time", row="smoker") plt.suptitle("Total Bill vs Tip, Faceted by Time and Smoker", y=1.02) plt.show()
这段代码使用 col="time" 和 row="smoker" 参数,创建了一个 2x2 的网格小图。每个子图代表了时间和是否吸烟的特定组合,例如 "Lunch" 且 "smoker=Yes"。
Seaborn 的关系图 (relplot(), scatterplot(), lineplot()) 是探索和展示数据集中变量关系的强大工具。它们通过灵活的视觉编码方式,能够将多个变量的信息同时呈现,帮助我们发现数据中的模式、趋势和分组关系。
关系图的应用场景广泛,包括但不限于:
探索性数据分析 (EDA):快速了解变量之间的关系,发现潜在的关联和模式。
特征工程:基于变量关系,选择合适的特征或创建新的特征。
模型评估:可视化模型的预测结果与实际值之间的关系,评估模型性能。
报告和演示:清晰、直观地呈现数据分析结果,支持决策制定。
本章要点回顾:
relplot() 是 Seaborn 关系图的统一入口,通过 kind 参数选择散点图 (scatterplot()) 或线图 (lineplot())。
散点图 (scatterplot()) 用于展示两个数值变量之间的关系,并可通过 hue, size, style 等参数增强视觉编码。
线图 (lineplot()) 用于展示一个变量随另一个变量变化的趋势,默认进行聚合估计和误差范围展示。
col, row, col_wrap 参数用于创建小图 (facets),根据分类变量分割数据,并在不同子图中绘制关系图。
关系图在数据分析和可视化中扮演重要角色,应用于 EDA, 特征工程, 模型评估, 报告演示等多个领域。
掌握 Seaborn 的关系图,将使您在数据探索和可视化方面如虎添翼,能够更有效地从数据中提取洞察,并清晰地传达您的发现。希望本章的内容能够帮助您深入理解和熟练运用 Seaborn 关系图,在数据分析的道路上更进一步。