百川归海,四类图统揽统计图:Seaborn|可视化系列03

Seaborn简介

Matplotlib虽然提供了丰富而强大的接口用于数据的可视化,但在展现多类数据关系时,需要较多数据处理过程,语句就变得繁琐,因此seaborn针对这类需求,基于matplotlib提供了更高层的接口,擅长统计数据的可视化。seaborn可视化的写法和matplotlib基本相同。其代码框架如下:

1
2
3
4
5
import seaborn as sns  #导入seabron库
tips = pd.read_excel('tips.xlsx') #dataframe数据
sns.relplot(x="total_bill", y="tip", col="time",
hue="smoker", style="smoker", size="size",
data=tips)

效果图

seaborn对pandas数据结构的支持非常好,能充分利用DataFrame的特点而不需要做格式转换。别期待着只用seaborn绘制出各种常用图表,它更专注于展示统计数据里的信息,因此,我们换个角度,从数据本身的分布和数据列之间的关系来看可视化。seaborn没有直接枚举各种图的接口,而是抽象为了四种relplot、regplot、catplot及distplot,分别对应:数据关联、回归、分类变量和数据分布。

关联 relplot

seaborn对于数据间的关联关系,相关可视图封装为sns.relplot()。rel指的是Relational,擅长处理两个变量或多个变量之间的关联关系可视化。

relplot(x,y,data)默认是画出两个变量x,y的散点图以体现data中x列和y列的数据关系。

relplot的参数如下:

  • data、x、y:分别是数据集、x轴对应值(data里的某一列的列名)、y轴对应值;
  • hue:色调,对数据的一种分类,通过颜色进行区分;如何指定颜色映射的规则呢?如Q1对应黄色,Q2对应青色?可通过palette及hue_norm/hue_order等参数进行定义;
  • kind:绘制图表的类型,relplot有两种选择,分别为"scatter""line",默认是散点图,也即scatter;
  • style:映射不同的散点形状,圆形、三角形、十字等,容易想到ax.plot()里的标记字符fmt;
  • palette:调色板,指定hue的颜色映射用;
  • size:映射散点的大小;
  • sizes:控制散点大小的范围,和size搭配着用,如sizes=(10,100)就把size对应列的值标准化到[10,100];
  • col、row:根据col和row参数决定分面后图的个数;

总结如图:

relplot参数卡片

绘制最基础散点图以直观展现x和y的关系,只需要写relplot(x,y,data),而要用颜色做分类、设置不同数据点形状及大小时,不需要像matplotlib一样先自己对数据做筛选,再调用多个ax.plot(x1,y1)来绘制。而是写sns.relplot(x=”total_bill”, y=”tip”, hue=”smoker”, size=”size”,data=tips)。

从本文的示例代码能看到的是,seaborn大部分都只需要调用一个函数,传参出图不墨迹,不需要自己写细节的数据处理代码。这就是高层次封装的意义。

relplot默认绘制的是散点图,设置参数kind="line"可以将点连成线,也就是绘制折线图表示x和y的关系。

示例代码如下:

1
2
3
df=pd.DataFrame({'x':list(range(1,8)),
'y':[i**3 for i in range(1,8)]})
sns.relplot(x='x',y='y',data=df,kind='line')

回归 regplot

x和y之间的关系除了靠我们直观地看出来之外,我们需要有更量化的数据证据,统计数据少不了用统计的手段处理,回归曲线就是很好地表达数据关系的一种手段。sns.regplot(x,y,data)用于绘制散点+回归曲线图,默认包含置信区间,主要还是线性回归。reg表示的是Regression,regplot()绘图效果及主要参数如下:

regplot

regplot()主要参数和relplot()挺类似,多了关于统计回归的个性化参数,且没有kind参数,

  • data、x、y:分别对应数据集、x轴对应值、y轴对应值;
  • x_estimator:是否显示x的估计量;
  • ci:回归的置信区间范围,在 0~100之间;
  • x_ci:可选”ci”或”sd”;
  • order:如果大于1,会使用numpy.polyfit来绘制高阶回归;
  • logx:如果是True,就变成了计算 y~log(x)的回归关系;
  • robust:如果是true,会使用统计模型考虑回归的鲁棒性,忽略异常值;
  • logistic:是否使用逻辑回归;
  • marker:散点的标记字符;
  • color:控制散点和回归线的颜色;

regplot()进行非线性回归的代码如下,主要是改了order参数,示例数据建的是一个y=x^3的数据集。

1
2
df=pd.DataFrame({'x':list(range(1,8)),'y':[i**3 for i in range(1,8)]})
sns.regplot(x="x", y="y", data=df,order=2, ci=None)

03-07-0-1-2

Regression部分的接口还有.lmplot()residplot()可以用,lmplot扩展了regplot的分面绘图功能,关于分面后续再展开,residplot用于绘制线性回归的残差(residuals)。对数据分类绘制多条回归线的代码如下:

1
2
sns.lmplot(x="total_bill", y="tip", 
hue="smoker", data=tips,markers=["o", "x"])

和Altair、plotnine、ggplot等可视化库一样,seaborn提供了好多个数据集,涵盖了各种数据关系和数据特征,方便教学使用,其中就包括久负盛名的iris(鸢尾花数据集)、titanic(泰坦尼克号船员数据集)等。通过iris=sns.load_dataset('iris')载入为标准的DataFrame格式,上一段绘制回归曲线就用到了seaborn提供的tips数据集。通过sns.get_dataset_names()可参看seaborn库所有的数据集名称。

分布 distplot

数据列与列之间隐藏着某种关系,我们很关注。我们也关心数据列内部的分布,是平均分布、随机分布还是聚集分布??是每天花钱一样多还是某天就花了预算的80%?

数据的分布情况seaborn的绘制接口是sns.distplot(a,bins),其主要参数和示例效果如下:

03-02-distplot-428-01

distplot()参数:

  • a:一个一维的数组,没有data参数了,需要写df[‘a’]传入一个Series,不支持sns.distplot(a='x',data=df) 写法是一种遗憾,至少本文发出时这么写seaborn会报错:got an unexpected keyword argument ‘data’;
  • bins:分箱数,对应matplotlib的hist()的bins参数;
  • hist:默认distplot会画直方图和密度曲线,hist=False则只画密度曲线;
  • kde:核密度估计(kernel density estimate),如果要只显示直方图呢?靠的就是kde参数,设置kde=False则只画分布直方图,没有密度曲线了;
  • rug:在直方图基础上再绘制地毯图效果,可以用sns.kdeplot(a)只画地毯图;
  • vertical:是否画垂直的直方图,类似条形图对应柱状图,vertial=True则绘制转了90度的直方图,分面的时候用得到;

两个维度上的数据分布情况我们也很关心,seaborn也提供了相应的接口,用到的就是kdeplot,示例效果如下:

1
sns.kdeplot(tips['total_bill'],tips['tip'])

kdeplot

分类变量 catplot

统计数据也不总是数值类型的,也会包含分类类型的数据(Categorical),例如餐饮消费数据可以分早餐、午餐、晚餐。分类数据的特点是两个类别间不一定等间隔划分,周一到周二间隔是24小时,但早餐到午餐的间隔和午餐到晚餐的间隔就不一致,又如地震四级到五级的间隔与五到六级间隔的区别。

对于单一变量,我们可以统计出其在列中的出现次数,绘制柱状图、饼图等,用Matplotlib绘制需要自己做数据透视或value_counts()操作。seaborn将分类变量相关的可视图表封装在sns.catplot()里。

catplot

catplot参数:

  • data、x、y:分别对应数据集、x轴对应值、y轴对应值,x会默认是一个分类变量,不是连续的数值;
  • hue:色调,将数据列映射到颜色;
  • orient:水平方向还是垂直方向上的分类;类似于柱状图vs条形图,可选{‘v’,’h’},对应vertical,horizontal;
  • kind:绘制图表类型,目前有{“point”, “bar”, “strip”, “swarm”, “box”, “violin”, “boxen”} 8种可选,是目前四大接口里支持最多的,可分为三类:分类散点图、分类变量分布图和分类变量估计图;各种有对应的plot一级接口,例如 .catplot(x,y,data,kind=’point’) 也可以写 .pointplot(x,y,data),其他的也类似;

统计tips数据集晚餐和午餐的出现次数,变成柱状图:

1
sns.catplot(x='time',y='total_bill',data=tips,kind='bar') 

03-07-0-0-9

countplot和barplot有些许不同,countplot不展示统计值的置信区间,countplot如果省略x而给y传参,得到的是条形图效果。

03-07-0-0-8

箱线图是在数据分析中高频出现的图,总览数据分布的时候又不失细节,绘制变量的箱线图也只需要一行代码:

1
sns.catplot(x='time',y='tip',data=tips,kind='box') 

03-07-0-0-4

可以看出晚餐在tips上数值范围更广,中位数也更高。

小提琴图比起箱线图,更好地利用宽度的变化来展现在同一个y处数据点的分布,绘制的形状像一个小提琴因此叫小提琴图(violin)。同样的数据列,绘制为小提琴图效果如下:

1
sns.catplot(x='time',y='tip',data=tips,kind='violin') 

03-07-0-0-5

kind='point'绘制包含置信区间的点+折线图,端点有置信区间。

1
sns.catplot(x="time", y="total_bill",hue="smoker",kind="point",data=tips, dodge=True)

03-07-0-1-7

分面与子图

为了更好地展现数据间的关系,我们会需要将多张图排列展现多指标的情况,需要结合大小图突出信息。Facet提供了相应的接口。最常用的是pairplotjointplot

1
2
3
g = sns.FacetGrid(tips, col="time")
g.map(plt.hist, "tip");
sns.pairplot(tips, hue="time", diag_kind="kde", height=2.5)

通过g = sns.FacetGrid(tips, col="time")可根据tips数据集的time列构建出多张图,每个time的取值(一般是分类变量)对应一张图,col参数在relplot的实践中提到过,通过g.map(plt.hist, "tip")应用直方图,效果如下:

03-07-0-1-1

结合回归曲线图和直方图:

1
sns.jointplot(x="total_bill", y="tip", data=tips,kind="reg")

03-07-0-1-4-jointplot

热力图可以展现一个矩阵类型的数据,用来展现x和y可能存在的某种模式,除了地理上的分布模式外,日历图是热力图的一个经典例子,基于tips数据的热力图绘制效果如下:

1
sns.heatmap(tips.loc[:,['total_bill','tip','size']].head(10), cmap="YlGnBu")

03-07-0-1-5

可视化时除了图表类型的挑选外,为了更好看及主题一致性等目的,颜色和样式的个性化配置也是很重要的,可视化库自然不能忽略相关的接口,seaborn有个总览的sns.set()接口,也有sns.set_palette("husl")sns.set_style("darkgrid",{"axes.facecolor": ".9"})sns.set_context("paper")可以用,seaborn内置了挺多色盘,可以通过sns.dark_palette()类似的语句获取色盘,通过sns.set_palette(sns.color_palette(["#9b59b6", "#3498db", "#95a5a6"]))设置个性化色盘。

seaborn的数据集挂在https://github.com/mwaskom/seaborn-data下,在使用sns.load_dataset(‘iris’)如果遇到
报错(timeout error、URLError、OSError或其他),可以从这个github地址直接下载数据再通过pd.read_csv()导入使用,整个数据集合一共4.5MB,占资源并不大。
根据数据的类型选择可视化类型可以参考data-to-viz.com

总结

可视化图表类型众多,echarts的案例菜单栏就分了27种有效图表、antv的案例菜单目前分了14种可视图,百川归海,seaborn将统计数据的可视化分为了四类,简化了绘图语句,并提供了多套配色和主题效果可以选择,让我们节约在绘图上的时间,更好地探索数据中的信息。因为seaborn是基于matplotlib的,两者可以很好地协作,通过调用不同层级的接口来实现更精细的需求。

seaborn目前是0.10.1版本,例子和API文档都还不够丰富,如很多绘图的API只有一段文字说明,没有绘制效果的例子;又如catplot的文档在最上面列出了hue,而详细解释部分没有hue。期待其后续更强大的功能和更详细的文档。

seaborn库API思维导图

参考资料