Fork me on GitHub

seaborn学习笔记(五):绘制多子图

In [1]:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
In [2]:
sns.set()
In [3]:
iris = sns.load_dataset('iris', data_home='.')
In [4]:
iris.head(2)
Out[4]:
 
 sepal_lengthsepal_widthpetal_lengthpetal_widthspecies
0 5.1 3.5 1.4 0.2 setosa
1 4.9 3.0 1.4 0.2 setosa
 

1 一图多绘

一图多绘是指在同一个坐标系绘制多个图表,这种方法原理是因为每个轴级绘图方法返回值都是AxesSubplot类实例,且每个轴级绘图方法都有ax参数可以接收一个AxesSubplot类实例进行指定坐标绘图:

In [5]:
axesSub = sns.boxplot(x='species', y='sepal_length', data=iris)
axesSub = sns.stripplot(x='species', y='sepal_length', data=iris, ax=axesSub)  # ax=axesSub,指定坐标性, 在之前箱型图基础上,继续绘制条带图
axesSub = sns.lineplot(x='species', y='sepal_length', data=iris, ax=axesSub)  # ax=axesSub,指定坐标性, 在之前箱型图基础上,继续绘制折线图
 
 

2 ax:指定子图坐标系

这个方法在此前介绍各绘图方法时,也有介绍并多次使用过,那就是各轴级绘图方法的ax参数传递坐标系,这种方法配合matplotlib的subplots()方法,是我认为最灵活,可定制化程度最高的一种多子图绘图方法,可以实现每一个子图都绘制不同种类的图表:

In [6]:
fig, ax =plt.subplots(1,3,constrained_layout=True, figsize=(12, 3))
axesSub = sns.boxplot(x="species", y="sepal_length", data=iris, ax=ax[0])
axesSub.set_title('boxplot')
axesSub = sns.stripplot(x="species", y="sepal_length", data=iris, ax=ax[1])
axesSub.set_title('stripplot')
axesSub = sns.histplot(x="sepal_length", data=iris, ax=ax[2])
_ = axesSub.set_title('histplot')
 
 

3 PairGrid:成对关系网格子图

PairGrid用于绘制数据集中成对关系的子图网格。此类将数据集中的每个变量映射到多个轴的网格中的列和行。可以使用不同的轴级绘图函数来绘制上三角和下三角的双变量图,并且对角线上可以显示每个变量的边际分布。它还可以通过hue参数用不同颜色绘制不同的数据子集来表示附加级别的条件化。这使用颜色来解析第三维的元素,但只是在彼此之上绘制子集,并且不会像接受hue的轴级函数那样为特定可视化定制hue参数。

 
  • hue:将绘图的不同面映射为不同的颜色
  • hue_order:字符串组成的list,设置hue后设置各颜色顺序
  • hue_kws:要插入到绘图调用中的其他关键字参数,以使其他绘图属性在色调变量的不同级别(例如散点图中的标记)之间变化。例如按颜色使用不同标记,hue_kws={"marker": ["o", "s", "D"]}
  • palette:调色板
  • vars: 同时指定x轴、y轴绘图字段,否则使用所有数值型字段
  • x_vars:指定x轴绘图字段
  • y_vars:指定y轴绘图字段
  • height标量,可选,每个刻面的高度(以英寸为单位)
  • aspect:标量,可选,aspect 和 height 的乘积得出每个刻面的宽度(以英寸为单位)
  • despine:布尔值,可选,从图中移除顶部和右侧外边框。
  • dropna:布尔值,可选,在绘图之前删除数据中的缺失值。
 

3.1 map方法:指定绘图方法

PairGrid所有参数中,只有data是必传参数,实例化时,seaborn会根据传入数据集的各个字段情况,绘制n行n列个坐标系,但仅限于绘制坐标系,坐标系中并未有任何图像,后续需通过调用map方法指定绘图方法后才会完成绘图。注意,在map方法文档中明确说明,此方法的作用是用同一方法在所有子图进行绘图,所以PairGird类绘图的所有子图,都是同类图表。

PairGrid类实例化时,只传递data参数,则绘制所有字段的子图,继续通过map方法传递sns.scatterplot作为绘图方法绘制散点图,当然,也可以传入其他绘图方法,绘制其他图形。在对角线上的图形,由于x轴和y轴都是同一字段,所以图形呈45度角直线,但并无实际意义。

In [7]:
g=sns.PairGrid(iris)
g=g.map(sns.scatterplot)
 
 

3.2 hue:根据指定字段绘制不同颜色图形

 

在实例化PairGrid类时,通过指定hue参数,可以根据字段绘制不同颜色图像,不过注意,默认情况下是没有图例的,后续需要调用add_legend()添加图例:

In [8]:
g=sns.PairGrid(iris, hue="species")
g=g.map(sns.scatterplot)
g = g.add_legend()  # 手动添加图例
 
 

3.3 vars:指定字段绘图

In [14]:
g = sns.PairGrid(iris, vars=["sepal_length", "sepal_width"])
g = g.map(sns.scatterplot)
 
 

3.3 height:指定子图高度

In [13]:
g = sns.PairGrid(iris, vars=["sepal_length", "sepal_width"],height=1.5)
g = g.map(sns.scatterplot)
 
 

3.4 g.map_diag()和g.map_offdiag():指定对角线和非对角线的绘图方法

g.map_diag()和g.map_offdiag()是与g.map类似的方法,区别在于g.map_diag()用于指定对角线上子图绘图方法,g.map_offdiag()用于指定非对角线上绘图方法,而g.map一次性指定所有子图绘图方法。

例如,非对角线绘制散点图,对角线上绘制直方图,可以这么做:

In [15]:
g = sns.PairGrid(iris)
g.map_offdiag(sns.scatterplot)  #指定非对角线绘图类型为散点图
g.map_diag(sns.histplot)  #指定对角线绘图类型为直方图
Out[15]:
<seaborn.axisgrid.PairGrid at 0x202d1d6f970>
 
 

无论是g.map,还是g.map_offdiag和g.map_diag,都可以传递指定的绘图方法本身的参数,对图形进行设置:

In [24]:
g = sns.PairGrid(iris)
g.map_offdiag(sns.scatterplot)  #指定非对角线绘图类型为散点图
g.map_diag(sns.histplot, color='red', element="step")  #指定对角线绘图类型为直方图
Out[24]:
<seaborn.axisgrid.PairGrid at 0x202d502a820>
 
 

3.5 g.map_upper和g.map_lower:指定上三角和下三角的绘图方法

In [28]:
g = sns.PairGrid(iris, hue="species")
g.map_diag(sns.histplot)  #指定对角线绘制直方图
g = g.map_upper(sns.scatterplot)  # 指定上三角绘制散点图
g = g.map_lower(sns.kdeplot)  # 指定下三角绘制核密度图
 
 

4 FacetGrid:多面网格子图

 

FacetGrid通过row, col, hue三个参数,最多从三个维度对数据进行分组,然后通过map方法指定绘图方法和x轴,y轴字段进行绘图,主要参数如下:

 
  • row, col, hue:定义数据子集的变量,这些数据将绘制在网格中的不同面上。row(行)纵向,col(列)横向,hue:颜色
  • col_wrap:每行最多显示子图个数
  • height标量,可选,每个刻面的高度(以英寸为单位)
  • aspect:标量,可选,aspect 和 height 的乘积得出每个刻面的宽度(以英寸为单位)
  • despine:布尔值,可选,从图中移除顶部和右侧外边框。
  • dropna:布尔值,可选,在绘图之前删除数据中的缺失值。
  • palette:颜色面板
  • row_order:字段显示顺序
  • col_order:字段显示顺序
  • hue_order:字段显示顺序
  • hue_kws:要插入到绘图调用中的其他关键字参数,以使其他绘图属性在色调变量的不同级别(例如散点图中的标记)之间变化。例如按颜色使用不同标记,hue_kws={"marker": ["o", "s", "D"]}
In [30]:
tips = sns.load_dataset('tips')
In [31]:
tips.head(2)
Out[31]:
 
 total_billtipsexsmokerdaytimesize
0 16.99 1.01 Female No Sun Dinner 2
1 10.34 1.66 Male No Sun Dinner 3
 

4.1 col, row, hue:分组统计字段

In [46]:
g = sns.FacetGrid(tips, col="time",  row="sex")
g.map(sns.histplot, "total_bill")
Out[46]:
<seaborn.axisgrid.FacetGrid at 0x202d927a430>
 
In [41]:
g = sns.FacetGrid(tips, col="time",  row="sex")
g.map(sns.scatterplot, "total_bill", "tip")
Out[41]:
<seaborn.axisgrid.FacetGrid at 0x202d8a7c310>
 
 

col="time", row="sex"仅表示分组统计的字段,左上角图表示按time、sex两个字段进行分组统计后,sex值为Male,time值为Launch的这一部分数据,以total_bill为x轴数据,以tip为y轴数据进行绘图。当然,可以只指定col或row,还可以添加hue。当使用了hue之后,建议通过add_legend()方法添加图例:

In [36]:
g = sns.FacetGrid(tips, col="sex", hue="smoker")
g.map(sns.scatterplot, "total_bill", "tip")
g = g.add_legend()
 
 

4.2 col_wrap:每行最多显示子图个数

In [48]:
g = sns.FacetGrid(tips, col="size", hue="smoker", col_wrap=4)  # 每行最多显示4个子图,所以分两行显示了,第二行2个子图
g.map(sns.scatterplot, "total_bill", "tip")
g = g.add_legend()
 
 

4.3 height, aspect:指定子图高度、宽高比

In [54]:
g = sns.FacetGrid(tips, col="day", height=2.5, aspect=1.5)
g.map(sns.histplot, "total_bill")
Out[54]:
<seaborn.axisgrid.FacetGrid at 0x202db5fc1f0>
 
 

4.4 g.refline:添加辅助线

In [55]:
g = sns.FacetGrid(tips, col="time", margin_titles=True)
g.map_dataframe(sns.scatterplot, x="total_bill", y="tip")
g.refline(y=tips["tip"].median())
 
 

4.5 添加文本说明

In [56]:
def annotate(data, **kws):
    n = len(data)
    ax = plt.gca()
    ax.text(.1, .6, f"N = {n}", transform=ax.transAxes)

g = sns.FacetGrid(tips, col="time")
g.map_dataframe(sns.scatterplot, x="total_bill", y="tip")
g.map_dataframe(annotate)
Out[56]:
<seaborn.axisgrid.FacetGrid at 0x202d5bd2670>
 
posted @ 2022-02-23 09:45  奥辰  阅读(16744)  评论(0编辑  收藏  举报