import seaborn as sns
sns.set_theme()
penguins = sns.load_dataset("penguins", data_home='seaborn-data',cache=True)
sns.histplot(data=penguins, x="flipper_length_mm", hue="species", multiple="stack")
<AxesSubplot: xlabel='flipper_length_mm', ylabel='Count'>
除了类似但可能不太熟悉的选项,例如核密度估计:
sns.kdeplot(data=penguins, x="flipper_length_mm", hue="species", multiple="stack")
<AxesSubplot: xlabel='flipper_length_mm', ylabel='Density'>
模块中的函数共享大量底层代码,并提供库的其他组件(如上面的示例的参数multiple="stack"
)中可能不存在的类似功能。它们旨在促进在浏览数据集时在不同的视觉表示形式之间切换,因为不同的表示形式通常具有互补的优势和劣势。
图形级函数与轴级函数
除了不同的模块外,海洋功能还有“轴级”或“图形级”的横切分类。上面的示例是轴级函数。它们将数据绘制到单个matplotlib.pyplot.Axes
对象上,该对象是函数的返回值。
相比之下,图形级函数通过管理图形的 seaborn 对象(通常是 FacetGrid
)与 matplotlib 交互。每个模块都有一个图形级功能,为其各个轴级功能提供单一接口。组织看起来有点像这样:
例如,displot()
是分布模块的图形级函数。它的默认行为是绘制直方图,使用与histplot()
幕后相同的代码:
sns.displot(data=penguins, x="flipper_length_mm", hue="species", multiple="stack")
<seaborn.axisgrid.FacetGrid at 0x7fbbf0cd9c90>
要改为绘制核密度图,请使用与 kdeplot()
相同的代码,使用 kind
参数选择该图:
sns.displot(data=penguins, x="flipper_length_mm", hue="species", multiple="stack", kind="kde")
<seaborn.axisgrid.FacetGrid at 0x7fbbf0bb6310>
您会注意到,图形级图看起来与轴级图大多相似,但也存在一些差异。值得注意的是,图例被放置在情节之外。它们的形状也略有不同(稍后会详细介绍)。
图形级函数提供的最有用的功能是它们可以轻松创建具有多个子图的图形。例如,我们可以通过在图的各列上绘制每个分布来“分面”它们,而不是将每种企鹅的三个分布堆叠在同一轴上:
sns.displot(data=penguins, x="flipper_length_mm", hue="species", col="species")
<seaborn.axisgrid.FacetGrid at 0x7fbbf0bf8350>
图窗级函数包装其轴级对应函数,并将特定于种类的关键字参数(例如直方图的条柱大小)向下传递到基础函数。这意味着它们同样灵活,但有一个缺点:特定于种类的参数不会出现在函数签名或文档字符串中。它们的某些功能可能不太容易被发现,您可能需要查看文档的两个不同页面,然后才能了解如何实现特定目标。
轴级函数可生成独立的绘图
轴级函数的编写方式类似于 matplotlib 函数的直接替换。虽然它们会自动添加轴标签和图例,但它们不会修改绘制到的轴之外的任何内容。这意味着它们可以组合成任意复杂的 matplotlib 图形,并具有可预测的结果。
轴级函数在内部调用matplotlib.pyplot.gca()
,它与matplotlib状态机接口挂钩,以便它们在“当前活动的”轴上绘制它们的图。但它们还接受ax=
参数,该参数与面向对象接口集成,并允许您指定每个绘图应该放在哪里:
import matplotlib.pyplot as plt
f, axs = plt.subplots(1, 2, figsize=(8, 4), gridspec_kw=dict(width_ratios=[4, 3]))
sns.scatterplot(data=penguins, x="flipper_length_mm", y="bill_length_mm", hue="species", ax=axs[0])
sns.histplot(data=penguins, x="species", hue="species", shrink=.8, alpha=.8, legend=False, ax=axs[1])
f.tight_layout()
tips = sns.load_dataset("tips",data_home='seaborn-data',cache=True)
g = sns.relplot(data=tips, x="total_bill", y="tip")
g.ax.axline(xy1=(10, 2), slope=.2, color="b", dashes=(5, 2))
<matplotlib.lines._AxLine at 0x7fbbf08ad7d0>
g = sns.relplot(data=penguins, x="flipper_length_mm", y="bill_length_mm", col="sex")
g.set_axis_labels("Flipper length (mm)", "Bill length (mm)")
<seaborn.axisgrid.FacetGrid at 0x7fbbf088b7d0>
指定图形尺寸
要增加或减少matplotlib图的大小,您可以在全局rcParams中设置整个图的宽度和高度,同时设置图(例如使用matplotlib.pyplot.subplots()
的figsize
参数),或者通过调用图对象上的方法(例如matplotlib. figure .set_size_inches()
)。当在seaborn中使用轴级函数时,同样的规则也适用:绘图的大小取决于它所在的图形的大小和该图形中的轴布局。
在使用图形级功能时,有几个关键的区别。首先,函数本身具有控制图形大小的参数(尽管这些参数实际上是管理图形的底层FacetGrid
的参数)。其次,这些参数,height
和aspect
,参数化大小与matplotlib中的width
,height
参数化略有不同(使用seaborn参数,width = height * aspect
)。最重要的是,参数对应于每个子图的大小,而不是整个图的大小。
为了说明这些方法之间的区别,下面是带有一个子图的matplotlib.pyplot.subplots()
的默认输出:
f, ax = plt.subplots()
具有多列的图形将具有相同的整体大小,但轴将被水平挤压以适合空间:
f, ax = plt.subplots(1, 2, sharey=True)
相反,由图形级函数创建的绘图将是方形的。为了演示这一点,让我们直接使用FacetGrid
设置一个空图。这发生在后台函数中,如relplot()
, displot()
或catplot()
:
g = sns.FacetGrid(penguins)
添加其他列时,图形本身将变宽,因此其子图具有相同的大小和形状:
g = sns.FacetGrid(penguins, col="sex")
您可以调整每个子图的大小和形状,而无需考虑图中的行和列总数:
g = sns.FacetGrid(penguins, col="sex", height=3.5, aspect=.75)
结果是,您可以分配刻面变量,而无需停下来考虑需要如何调整总图形大小。缺点是,当您确实想更改图形大小时,您需要记住,事情的工作方式与 matplotlib 中的工作方式略有不同。
图形级函数的相对优点
以下是我们上面讨论的优缺点的总结:
优势 | 缺点 |
通过数据变量轻松分面 | 许多参数不在函数签名中 |
默认情况下,图例在绘图之外 | 不能是更大的 matplotlib 图的一部分 |
轻松的图形级定制 | 与 matplotlib 不同的 API |
不同的图形尺寸参数化 | 不同的图形尺寸参数化 |
总的来说,图形级函数增加了一些额外的复杂性,可能会让初学者更加困惑,但它们独特的功能赋予了它们额外的功能。教程文档主要使用图形级函数,因为它们生成的绘图稍微清晰一些,我们通常建议在大多数应用程序中使用它们。它们不是一个好的选择的一种情况是,当你需要制作一个复杂的、独立的人物,组成多种不同的情节类型时。此时,建议直接使用 matplotlib 设置图形,并使用轴级函数填充各个组件。
组合数据的多个视图
海产的两个重要绘图函数不能很好地适用于上面讨论的分类方案。jointplot()
和pairplot()
这两个函数使用来自不同模块的多种绘图来在单个图中表示数据集的多个方面。这两个绘图都是图形级函数,默认情况下创建具有多个子绘图的图形。但是它们使用不同的对象来管理图形:分别是JointGrid
和PairGrid
。
Jointplot()
绘制两个变量的关系或联合分布,并添加分别表示每个变量的单变量分布的边缘轴:
sns.jointplot(data=penguins, x="flipper_length_mm", y="bill_length_mm", hue="species")
<seaborn.axisgrid.JointGrid at 0x7fbbf06aa450>
pairplot()
是相似的——它结合了联合视图和边际视图——但不是专注于单一关系,而是同时可视化每个成对的变量组合:
sns.pairplot(data=penguins, hue="species")
<seaborn.axisgrid.PairGrid at 0x7fbbf0498a10>
在幕后,这些函数使用了你已经见过的轴级函数(scatterplot()
和kdeploy()
),它们也有一个kind
参数,可以让你快速交换不同的表示:
sns.jointplot(data=penguins, x="flipper_length_mm", y="bill_length_mm", hue="species", kind="hist")
<seaborn.axisgrid.JointGrid at 0x7fbbeb9a7c50>