灵活的使用seaborn,先掰扯axes-level和figure-level关系
-
坐标轴级别(axes-level)绘图函数 -
图形级别(figure-level)绘图函数
6.1 axes-level绘图函数
axes-level绘图函数是将数据绘制在matplotlib.pyplot.Axes对象上,此类函数可以直接使用matplotlib rcParams中的参数。
例如,使用章节3.2.2 penguins数据集,直方图展示不同“企鹅的种类”的"喙长 (毫米)"分布关系时,可直接使用axes-level绘图函数histplot,
import seaborn as sns
import pandas as pd
import matplotlib as mpl
penguins = pd.read_csv(
'./sns_data/penguins.csv') #使用pandas读取章节3.2.2 penguins数据集数据
g = sns.histplot(
data=penguins, #使用axes-level函数histplot
x="喙长 (毫米)",
hue="企鹅的种类",
palette=["#006a8e", "#b1283a", "#a8a6a7"],
multiple="stack")
print(type(g))
其中,g是一个matplotlib.pyplot.Axes对象(见上方红色箭头)。更多axes-level绘图函数,如下图中蓝色框子后的函数,例如,scatterplot、lineplot、stripplot、swarmplot等函数。
6.2 figure-level绘图函数
figure-level绘图函数将数据绘制在seaborn.axisgrid.FacetGrid对象上,此类函数拥有区别于matplotlib rcParams中的参数,每个figure-level绘图函数都提供了统一的axes-level接口。
例如,6.1章节的图也可以使用figure-level绘图函数displot,只需要指定kind="hist",
g = sns.displot(
data=penguins, ##使用figure-level函数displot
x="喙长 (毫米)",
hue="企鹅的种类",
multiple="stack",
palette=["#006a8e", "#b1283a", "#a8a6a7"],
kind="hist") #kind="hist"等价于axes-level函数histplot
print(type(g))
其中,g是一个seaborn.axisgrid.FacetGrid对象(见上方红色箭头)。更多figure-level绘图函数,如下图中蓝色框子内的jointplot、relplot、displot等。
6.3 figure-level、axes-level比较
大部分情况下,figure-level和axes-level函数功能非常相似,但也存在一些差异,例如,figure-level中图例被放置在图形之外,axes-level中则将图例被放置在图形之内(注意比较6.1章节和6.2章节)。
下文详细介绍figure-level和axes-level的差异。
- 6.3.1 figure-level多子图
figure-level最擅长多子图(subplot)绘制。例如,6.1章节和6.2章节中的堆叠直方图不容易直观看出每一种企鹅的“喙长 (毫米)”分布,解决该问题,可以尝试多子图,每一种企鹅绘制一个“喙长 (毫米)”分布直方图,figure-level函数一行代码实现多子图,
sns.displot(
data=penguins,
x="喙长 (毫米)",
hue="企鹅的种类", #按照"企鹅的种类"绘制子图
col="企鹅的种类", #图形按照"企鹅的种类"按行绘制
palette=["#006a8e", "#b1283a", "#a8a6a7"])
虽然figure-level多子图绘制很便捷,但是,如果想单独设置某个子图就不够灵活,例如,
sns.displot(
data=penguins,
x="喙长 (毫米)",
hue="企鹅的种类",
col="企鹅的种类",
binwidth=10, #设置柱子的宽度
palette=["#006a8e", "#b1283a", "#a8a6a7"])
binwidth可以高效设置所有子图的bin宽度,并不能设置某一个子图。
- 6.3.2 axes-level多子图个性化
axes-level也可以绘制多子图,需要通过参数ax指定子图,seaborn内部调用matplotlib.pyplot.gca()激活当前子图为需要绘图的对象,例如,
import matplotlib.pyplot as plt
fig, axs = plt.subplots( #subplots添加3个子图
1,3,figsize=(8, 4),
gridspec_kw=dict(width_ratios=[1, 1, 1]))
colormaps = ["#006a8e", "#b1283a", "#a8a6a7"]
for i, species in enumerate(penguins['企鹅的种类'].unique()):
data = penguins[penguins['企鹅的种类'] == species]
sns.histplot(
data=data,
x='喙长 (毫米)',
ax=axs[i], # 参数ax激活当前子图axs[i]为需要绘图的对象
color=colormaps[i])
axs[i].set_title("企鹅的种类=%s" % species)
plt.tight_layout()
效果类似figure-level绘制多子图,但是,axes-level代码量大大增加。相比于figure-level,axes-level更擅长每个子图的个性化,例如,
import matplotlib.pyplot as plt
f, axs = plt.subplots( #subplots添加两个子图
1,
2,
figsize=(8, 4),
gridspec_kw=dict(width_ratios=[4, 3]))
sns.scatterplot(data=penguins,
x="喙深 (毫米)",
y="喙长 (毫米)",
palette=["#006a8e", "#b1283a", "#a8a6a7"],
hue="企鹅的种类",
ax=axs[0]) #参数ax激活当前子图axs[0]为需要绘图的对象
sns.histplot(data=penguins,
x="企鹅的种类",
hue="企鹅的种类",
palette=["#006a8e", "#b1283a", "#a8a6a7"],
shrink=.8,
alpha=.8,
legend=False,
ax=axs[1]) #参数ax激活当前子图axs[1]为需要绘图的对象
f.tight_layout()
- 6.3.3 figure-level全局个性化
figure-level拥有很多区别于matplotlib rcParams中的有用参数,这些参数seaborn独有,从全局设置图形,全局个性化是在seaborn.axisgrid.FacetGrid对象上设置。例如,修改多个子图x坐标轴上的标签,
import seaborn as sns
import pandas as pd
import matplotlib as mpl
g = sns.displot(
data=penguins,
x="喙长 (毫米)", #修改前,多个子图x坐标轴上的标签取x变量名
hue="企鹅的种类",
col="企鹅的种类",
palette=["#006a8e", "#b1283a", "#a8a6a7"])
修改前,多个子图x坐标轴上的标签取x变量名“喙长 (毫米)”。
一行代码修改多个子图x坐标轴上的标签“喙长 (mm)”,更多全局设置函数见后文。figure-level也可以调用axes-level个性化图形,例如,
import seaborn as sns
import pandas as pd
import matplotlib as mpl
g = sns.relplot(data=tips, x="消费金额 ($)", y="小费金额 ($)", color="#b1283a")
#调用axes-level方法matplotlib.lines._AxLine添加趋势线
g.ax.axline(xy1=(10, 2), slope=.2, color="#006a8e", dashes=(5, 2))
- 6.3.4 figure-level设置图形大小
axes-level设置图形的大小同matplotlib中figzie参数,例如,
# 第一张图代码
import matplotlib.pyplot as plt
f, ax = plt.subplots(figsize=(6, 4)) #figsize设置整个图形宽6、高4
# 第二张图代码
f, ax = plt.subplots(1, 2, figsize=(6, 4)) #两个子图均分整个图形大小
效果如下,
figure-level设置图形的大小同axes-level存在巨大差异,通过height设置每个图形高度,通过height * aspect设置每个图形宽度,例如,
# 第一张图代码
sns.FacetGrid(data=penguins, height=3, aspect=1)
# 第二张图代码
sns.FacetGrid(data=penguins, height=3, aspect=1, col='性别') #设置每个子图大小
sns.FacetGrid(
data=penguins,
col='性别',
height=3, #通过height设置每个子图高度
aspect=0.75) #通过height * aspect设置每个图形宽度
- 6.4 figure-level、axes-level小结
figure-level和axes-level在简单图形上,效果几乎一样;figure-level会生成更清晰、简洁的图形,在多子图、全局统一设置方面优势明显;axes-level在需要绘制多个子图,且每个子图上绘制不同图形时优势明显。
如何加入学习 《保姆级seaborn教程》
👇加入学习 ( 收费、 务必备注:169 )
-
代码(复制即可运行) -
在线教程文档(方便后续更新) -
依赖数据(免费下载) -
交流群 -
后续更新