Seaborn简介
Matplotlib虽然提供了丰富而强大的接口用于数据的可视化,但在展现多类数据关系时,需要较多数据处理过程,语句就变得繁琐,因此seaborn针对这类需求,基于matplotlib提供了更高层的接口,擅长统计数据的可视化。seaborn可视化的写法和matplotlib基本相同。其代码框架如下:
1 | import seaborn as sns #导入seabron库 |
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参数决定分面后图的个数;
总结如图:
绘制最基础散点图以直观展现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 | df=pd.DataFrame({'x':list(range(1,8)), |
回归 regplot
x和y之间的关系除了靠我们直观地看出来之外,我们需要有更量化的数据证据,统计数据少不了用统计的手段处理,回归曲线就是很好地表达数据关系的一种手段。sns.regplot(x,y,data)用于绘制散点+回归曲线图,默认包含置信区间,主要还是线性回归。reg表示的是Regression,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 | df=pd.DataFrame({'x':list(range(1,8)),'y':[i**3 for i in range(1,8)]}) |
Regression部分的接口还有.lmplot()
和 residplot()
可以用,lmplot扩展了regplot的分面绘图功能,关于分面后续再展开,residplot用于绘制线性回归的残差(residuals)。对数据分类绘制多条回归线的代码如下:
1 | sns.lmplot(x="total_bill", y="tip", |
和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)
,其主要参数和示例效果如下:
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']) |
分类变量 catplot
统计数据也不总是数值类型的,也会包含分类类型的数据(Categorical),例如餐饮消费数据可以分早餐、午餐、晚餐。分类数据的特点是两个类别间不一定等间隔划分,周一到周二间隔是24小时,但早餐到午餐的间隔和午餐到晚餐的间隔就不一致,又如地震四级到五级的间隔与五到六级间隔的区别。
对于单一变量,我们可以统计出其在列中的出现次数,绘制柱状图、饼图等,用Matplotlib绘制需要自己做数据透视或value_counts()操作。seaborn将分类变量相关的可视图表封装在sns.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') |
countplot和barplot有些许不同,countplot不展示统计值的置信区间,countplot如果省略x而给y传参,得到的是条形图效果。
箱线图是在数据分析中高频出现的图,总览数据分布的时候又不失细节,绘制变量的箱线图也只需要一行代码:
1 | sns.catplot(x='time',y='tip',data=tips,kind='box') |
可以看出晚餐在tips上数值范围更广,中位数也更高。
小提琴图比起箱线图,更好地利用宽度的变化来展现在同一个y处数据点的分布,绘制的形状像一个小提琴因此叫小提琴图(violin)。同样的数据列,绘制为小提琴图效果如下:
1 | sns.catplot(x='time',y='tip',data=tips,kind='violin') |
kind='point'
绘制包含置信区间的点+折线图,端点有置信区间。
1 | sns.catplot(x="time", y="total_bill",hue="smoker",kind="point",data=tips, dodge=True) |
分面与子图
为了更好地展现数据间的关系,我们会需要将多张图排列展现多指标的情况,需要结合大小图突出信息。Facet提供了相应的接口。最常用的是pairplot
和jointplot
1 | g = sns.FacetGrid(tips, col="time") |
通过g = sns.FacetGrid(tips, col="time")
可根据tips数据集的time列构建出多张图,每个time的取值(一般是分类变量)对应一张图,col参数在relplot的实践中提到过,通过g.map(plt.hist, "tip")
应用直方图,效果如下:
结合回归曲线图和直方图:
1 | sns.jointplot(x="total_bill", y="tip", data=tips,kind="reg") |
热力图可以展现一个矩阵类型的数据,用来展现x和y可能存在的某种模式,除了地理上的分布模式外,日历图是热力图的一个经典例子,基于tips数据的热力图绘制效果如下:
1 | sns.heatmap(tips.loc[:,['total_bill','tip','size']].head(10), cmap="YlGnBu") |
可视化时除了图表类型的挑选外,为了更好看及主题一致性等目的,颜色和样式的个性化配置也是很重要的,可视化库自然不能忽略相关的接口,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。期待其后续更强大的功能和更详细的文档。
参考资料