Python数据分析(六):数据可视化库之Seaborn
上一篇我们学习过了matplotlib库,现在我们学习一下seaborn库,seaborn是基于matplotlib的python数据可视化库,它提供了用于绘制引人入胜且内容丰富的统计图形的高级界面。由于seaborn是在matplotlib的基础上进行了更高级的API封装,从而使得作图更加容易,在大多数情况下使用seaborn能做出很具有吸引力的图,而使用matplotlib就能制作具有更多特色的图,应该把seaborn视为matplotlib的补充,而不是替代物。同时它能高度兼容numpy与pandas数据结构以及scipy与statsmodels等统计模式。
seaborn的安装过程我就不讲了,推荐大家安装anaconda,方便快速。接下来我们进行seaborn的学习:
1、matplotlib画图与seaborn比较
我们先用matplotlib库画sin(x)图,
import seaborn as sns
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
%matplotlib inline#直接显示
def sinplot(flip=1):
#在指定的间隔范围内返回均匀间隔的数字。step指定步长
x=np.linspace(0,14,100)#[0,14]的区间上找到100个点
for i in range(1,7):
plt.plot(x,np.sin(x+i*5)*(7-i)*flip)#sin图像
sinplot()
接下来我们seaborn库来画一个相同的图,比较一下不同点,
sns.set()#用seaborn默认的一些参数
sinplot()
可以看出,seaborn与matplotlib画出的图形差不多(有些差距可能比较大),seaborn封装了一些小细节看起来更舒服。
2、seaborn主题风格
seaborn有五种主题风格,分别是darkgrid、whitegrid、dark、white和ticks,我们分别来用这五种风格画图试试,
- whitegrid
sns.set_style("whitegrid")
data=np.random.normal(size=(20,6)) + np.arange(6)/2
sns.boxplot(data=data)#盒图
- darkgrid
sns.set_style("darkgrid")
data=np.random.normal(size=(20,6)) + np.arange(6)/2
sns.boxplot(data=data)#盒图
- white
sns.set_style("white")
sinplot()
- ticks
sns.set_style("ticks")#线段
sinplot()
- dark
sns.set_style("dark")
data=np.random.normal(size=(20,6)) + np.arange(6)/2
sns.boxplot(data=data)#盒图
我们还可以去边框,
sinplot()
sns.despine()#去掉某些轴
3、画各种类型的图
- 小提琴图
sns.violinplot(data)
sns.despine(offset=10)#设置离坐标轴的距离
- 盒图
sns.set_style("whitegrid")
sns.boxplot(data=data,palette="deep")#自定义调色板
sns.despine(left=True)
- 子图
with sns.axes_style("darkgrid"):#with代码里面的风格一样
plt.subplot(211)
sinplot()
plt.subplot(212)
sinplot(-1)
4、通过set_context()调整绘图元素
首先,可以通过sns.set()重置参数
sns.set()
四种预设,按相对尺寸的顺序(线条越来越粗),分别是paper,notebook, talk, and poster。notebook的样式是默认的,上面的绘图都是使用默认的notebook预设。
- paper
sns.set()
sns.set_context("paper")#别名
plt.figure(figsize=(8,6))
sinplot()
- talk
sns.set_context("talk")#别名
plt.figure(figsize=(8,6))
sinplot()
- poster
sns.set_context("poster")#别名
plt.figure(figsize=(8,6))
sinplot()
- notebook
通过更改context还可以独立地扩展字体元素的大小。(
sns.set_context("notebook",font_scale=1.5,rc={"lines.linewidth":3.5})#font_scale:字体大小
sinplot()
5、调色板
颜色很重要:
- color_palette() 能传入任何Matplotlib所支持的颜色
- color_palette() 不写参数则默认颜色
- set_palette() 设置所有图的颜色
1、分类调色板
当你区分没有固定顺序的离散数据块时,定性(或分类)调色板是最好的
current_palette=sns.color_palette()
sns.palplot(current_palette)
有6个不同的默认主题,叫做deep、muted、pastel、bright、dark和colorblind。
2、圆形彩色系统
当你有六个以上的分类要区分时,最简单的方法就是在一个圆形的颜色空间中画出均匀间隔的颜色(这样的色调会保持亮度和饱和度不变)。这是大多数的当他们需要使用比当前默认颜色循环中设置的颜色更多时的默认方案。
最常用的方法是使用hls的颜色空间,这是RGB值的一个简单转换
sns.palplot(sns.color_palette("hls",8))
比如,
data=np.random.normal(size=(20,8))+np.arange(8)/2 #正态分布,size表示输出size
sns.boxplot(data=data,palette=sns.color_palette("hls",8))
- hls_palette()函数来控制颜色的亮度和饱和
- l :亮度 lightness
- s : 饱和 saturation
sns.palplot(sns.hls_palette(8,l=.3,s=.8))
3、使用分类Color Brewer调色板
Color Brewer网站的一个不错的功能是,它提供了有关哪些调色板是色盲安全调色板的一些指导。有多种类型的色盲的,但最常见的变异导致难以区分红色和绿色。通常最好避免将红色和绿色用于需要根据颜色进行区分的绘图元素。
sns.palplot(sns.color_palette("Paired",10))#颜色成对
4、使用xkcd颜色调查中的命名颜色
不久前,xkcd进行了众包工作,以命名随机RGB颜色。这产生了一组954种名为colors的颜色,您现在可以使用
xkcd_rgb
字典在seaborn中进行引用:
plt.plot([0,1],[0,1],sns.xkcd_rgb["pale red"],lw=3)#lw指定线宽,[0,1][0,1]代表点
plt.plot([0,1],[0,2],sns.xkcd_rgb["medium green"],lw=3)
plt.plot([0,1],[0,3],sns.xkcd_rgb["denim blue"],lw=3)
color=["windows blue","amber","greyish","faded green","dusty purple"]
sns.palplot(sns.xkcd_palette(color))
5、连续色板
- 色彩随数据变换,比如数据越来越重要则颜色越来越深
sns.palplot(sns.color_palette("Blues"))
如果想要翻转渐变,可以在面板名称中添加一个_r后缀
sns.palplot(sns.color_palette("BuGn_r"))
- cubehelix_palette()调色板
色调线性变换
所述cubehelix调色板系统使得与亮度的线性增加或减小,在色调的一些变化顺序调色板。这意味着当转换为黑白(用于打印)或色盲人员查看时,色图中的信息将保留。
sns.palplot(sns.color_palette("cubehelix",8))
sns.palplot(sns.cubehelix_palette(8,start=.5,rot=-.75))#区间
sns.palplot(sns.cubehelix_palette(8,start=.75,rot=-.150))
- 自定义顺序调色板
sns.palplot(sns.light_palette("green"))#从浅到深
sns.palplot(sns.dark_palette("purple"))#从深到浅
sns.palplot(sns.light_palette("navy",reverse=True))
sns.palplot(sns.light_palette("green",reverse=True))
sns.palplot(sns.dark_palette("green"))#从深到浅
x,y=np.random.multivariate_normal([0,0],[[1,-.5],[-.5,1]],size=300).T#多元正态分布矩阵
#multivariate_normal(mean, cov, size=None, check_valid=None, tol=None)
# mean:均值,维度为1,必选参数;
# cov:协方差矩阵,必选参数;
# size: 指定生成矩阵的维度,若size=(1, 1, 2),则输出的矩阵的 shape 即形状为 1X1X2XN(N为mean的长度);
# check_valid:可取值 warn,raise以及ignore;
# tol:检查协方差矩阵奇异值时的公差,float类型;
pal=sns.dark_palette("green",as_cmap=True)#将green传进去
sns.kdeplot(x,y,cmap=pal)#从里到外,由浅入深
sns.palplot(sns.light_palette((210,90,60),input="husl"))#颜色空间
6、单变量分析绘图
%matplotlib inline
import numpy as np
import pandas as pd
from scipy import stats,integrate
import matplotlib.pyplot as plt
import seaborn as sns
sns.set(color_codes=True)
np.random.seed(sum(map(ord,"distributions")))
#ord()函数它以一个字符(长度为1的字符串)作为参数,返回对应的ASCII数值,或者Unicode数值,
#如果所给的Unicode字符超出了你的Python定义范围,则会引发一个TypeError的异常。
#利用np.random.seed()函数设置相同的seed,每次生成的随机数相同。如果不设置seed,则每次会生成不同的随机数
- 直方图
x=np.random.normal(size=100)
sns.distplot(x,kde=False)#直方图,x表示数据
#kde控制是否画kde曲线(和核密度有关,这里不讲)
sns.distplot(x,bins=20,kde=False)
使用
distplot()
将参数分布拟合到数据集,并在视觉上评估其与观测数据的对应程度:
x=np.random.gamma(6,size=200)
sns.distplot(x,kde=False,fit=stats.gamma)
绘制二元分布
根据均值和协方差生成数据
mean,cov=[0,1],[(1,.5),(.5,1)]
data=np.random.multivariate_normal(mean,cov,200)
df=pd.DataFrame(data,columns=["x","y"])
df
- 散点图
观测两个变量之间的分布关系最好用散点图,可视化双变量分布的最熟悉的方法是散点图,其中每个观察点的点均位于x和y值处。这与二维的地毯图相似。可以使用matplotlibplt.scatter
函数绘制散点图,这也是该jointplot()
函数显示的默认图样:
sns.jointplot(x="x",y="y",data=df)#散点图
- 六边形图
直方图的双变量类似物称为“六边形”图,因为它显示了落在六边形箱中的观测值。此图最适合于相对较大的数据集。可通过matplotlibplt.hexbin
函数以及中的样式来使用jointplot()
。在白色背景下看起来最好:
x,y=np.random.multivariate_normal(mean,cov,1000).T
with sns.axes_style("white"):
sns.jointplot(x=x,y=y,kind="hex",color="k")#颜色越深数据越多
7、双变量分析绘图
要在数据集中绘制成对的双变量分布,可以使用pairplot()
函数。这将创建轴矩阵,并显示DataFrame中每对列的关系。默认情况下,它还会在对角轴上绘制每个变量的单变量分布:
这里我们使用的数据集是鸢尾花的数据集,可以通过seaborn直接下载
iris = sns.load_dataset("iris")
sns.pairplot(iris);
8、回归分析绘图
seaborn中的回归图主要旨在添加可视指南,以帮助在探索性数据分析过程中强调数据集中的模式。也就是说,seaborn本身并不是统计分析的工具包。seaborn的目标是使通过可视化方式快速而轻松地浏览数据集变得容易,因为这样做与通过统计表浏览数据集一样重要。
这里我们使用的数据集是顾客给小费的情况:
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
sns.set(color_codes=True)
tips = sns.load_dataset("tips")
tips.head()
seaborn中的两个主要函数用于可视化通过回归确定的线性关系,即
regplot()
和lmplot()
,这里我们用的是regplot()
sns.regplot(x="total_bill",y="tip",data=tips)
sns.lmplot(x="total_bill",y="tip",data=tips)
sns.regplot(data=tips,x="size",y="tip")
sns.regplot(data=tips,x="size",y="tip",x_jitter=.05)#加上浮动
9、多变量分析绘图
分类散点图:
- stripplot()(带有kind="strip";默认值)
- swarmplot()(带有kind="swarm")
分类分布图: - boxplot()(带有kind="box")
- violinplot()(带有kind="violin")
- boxenplot()(带有kind="boxen")
分类估计图: - pointplot()(带有kind="point")
- barplot()(带有kind="bar")
- countplot()(带有kind="count")
sns.stripplot(x="day",y="total_bill",data=tips)
重叠是很常见的现象,但是重叠影响我们观察数据的量,该jitter参数控制抖动的大小或完全禁用它
sns.stripplot(x="day",y="total_bill",data=tips,jitter=True)
第二种方法是使用防止重叠的算法沿分类轴调整点。尽管它仅适用于相对较小的数据集,但它可以更好地表示观测值的分布。这种情节有时也被称为“beeswarm”,并在seaborn绘制
swarmplot()
,这是通过激活设置kind="swarm"
在catplot()
:
sns.swarmplot(x="day",y="total_bill",data=tips)
与关系图相似,可以通过使用hue语义为分类图添加另一个维度。(分类图当前不支持size或style语义)。每个不同的分类标绘函数对hue语义的处理都不同。对于散点图,仅需要更改点的颜色:
sns.swarmplot(x="day",y="total_bill",hue="sex",data=tips)
sns.swarmplot(x="total_bill",y="day",hue="time",data=tips)
- 盒图(箱线图)
- IQR即统计学概念四分位距,第一四分位与第三四分卫之间的距离
- N=1.5IQR如果一个值>Q3+N或<Q1-N,则为离群点
sns.boxplot(x="day",y="total_bill",hue="time",data=tips)
- 小提琴图
sns.violinplot(x="total_bill",y="day",hue="time",data=tips)#小提琴图
当hue参数只有两个级别时,也可以“拆分”小提琴,这样可以更有效地利用空间:
sns.violinplot(x="day",y="total_bill",hue="sex",data=tips,split=True)#split指定左右两边的属性
组合
swarmplot()
或striplot()
与箱形图或小提琴图结合使用以显示每个观察结果以及分布摘要也可能很有用:
sns.violinplot(x="day",y="total_bill",data=tips,inner=None)
sns.swarmplot(x="day",y="total_bill",data=tips,color="w",alpha=.5)#alpha表示透明度
- 类别内的统计估计
我们使用泰坦尼克数据来进行下一步分析,数据集还是用seaborn直接下载,
titanic=sns.load_dataset('titanic')
sns.barplot(x="sex",y="survived",hue="class",data=titanic)
在seaborn中,该barplot()
函数在完整的数据集上运行并应用函数以获取估计值(默认为均值)。当每个类别中都有多个观察值时,它还会使用自举法来计算估计值周围的置信区间,并使用误差线进行绘制:
- 点图
点图可以更好的描述变化差异,该pointplot()
功能提供了一种可视化相同信息的替代样式。该函数还使用另一轴上的高度对估计值进行编码,但是它不显示完整的条形图,而是绘制点估计值和置信区间。
sns.pointplot(x="sex",y="survived",hue="class",data=titanic)
#或者下面这种写法
sns.catplot(x="sex", y="survived", hue="class", kind="point", data=titanic);
当分类函数缺少style关系函数的语义时,将标记和/或线型以及色相一起更改以使图形最大程度地可访问并以黑白很好地再现仍然是一个好主意:
sns.pointplot(x="class",y="survived",hue="sex",data=titanic,palette={"male":"g","female":"m"},
markers=["^","o"],linestyles=["-","--"])#制定颜色、线条、标志
- 绘制"宽行"数据
sns.boxplot(data=iris,orient="h")#h表示横着画
多层面板分类图
sns.factorplot(x="day",y="total_bill",hue="smoker",data=tips)
sns.factorplot(x="day",y="total_bill",hue="smoker",data=tips,kind="bar")
sns.factorplot(x="day",y="total_bill",hue="smoker",col="time",data=tips,kind="swarm")
seaborn.catplot(x=None, y=None, hue=None, data=None, row=None, col=None, col_wrap=None, estimator=, ci=95, n_boot=1000, units=None, order=None, hue_order=None, row_order=None, col_order=None, kind='strip', height=5, aspect=1, orient=None, color=None, palette=None, legend=True, legend_out=True, sharex=True, sharey=True, margin_titles=False, facet_kws=None, **kwargs)
类别 | 格式 | 说明 |
---|---|---|
x,y,hue | data | 数据集变量的名称 |
data | DataFrame | 数据集 |
row,col | data中的变量名称,可选 | 数据中变量的名称,作用:设置分类变量将决定网格的分面。 |
col_wrap | int,可选 | 每行的最高平铺数 |
estimator | 向量->标量,可选 | 在每个分类中进行矢量到标量的映射 |
ci | float或“sd”或None,可选 | 置信区间 |
n_boot | int,可选 | 计算置信区间时要使用的引导程序迭代次数 |
units | 数据或矢量数据中变量的名称,可选 | 采样单位的标识符,将用于执行多级引导程序并考虑重复测量的设计。 |
order,hue_order | 字符串列表 | 对应排序列表 字符串列表 |
row_order,col_order | 字符串列表,可选 | 对应排序列表 字符串列表 |
kind | 字符串,可选 | 要绘制的绘图类型(对应于分类绘图功能的名称。选项包括"点","条形","条形","群","框","小提琴" |
height | 标量,可选 | 每个构面的高度(以英寸为单位) |
aspect | 标量,可选 | 每个小平面的长宽比,以便以英寸为单位给出每个小平面的宽度。aspect * height |
orient | “ v” 或 “ h”,可选 | 绘图的方向(垂直或水平)这通常是根据输入变量的dtype推断出来的,但可用于指定“分类”变量是数字时还是绘制宽格式数据时。 |
color | matplotlib颜色 | 所有元素的颜色,或渐变调色板的种子。 |
palette | 调色板名称,列表或字典,可选 | 用于hue变量的不同级别的颜色。应该是可以解释的内容color_palette(),或者是将色调级别映射到matplotlib颜色的字典。 |
legend | bool,可选 | 如果True并且存在hue变量,则在图上绘制图例。 |
legend_out | bool,可选 | 如果为True,则图的大小将被扩展,并且图例将在右中部的图的外部绘制。 |
share {x,y} | 布尔,“ col”或“ row”,可选 | 如果为true,则构面将在列之间共享y轴和/或在行之间共享x轴。 |
margin_titles | bool,可选 | 如果True为,则将行变量的标题绘制在最后一列的右侧。此选项是实验性的,可能并非在所有情况下都有效。 |
facet_kws | dict,可选 | 要传递给的其他关键字参数的字典FacetGrid。 |
kwargs | 键,值配对 | 其他关键字参数将传递给基础绘图功能。 |
sns.catplot(x="time",y="total_bill",hue="smoker",col="day",data=tips,kind="box",height=4,aspect=.5)
10、建立结构化的多图网格
条件小倍数
FacetGrid
当您要可视化数据集子集中的变量分布或多个变量之间的关系时,该类很有用。一个FacetGrid
最多可以被吸引到三个维度:row
,col
,和hue
。前两个与所得的轴数组有明显的对应关系。可以将色相变量视为沿深度轴的第三维,在其中用不同的颜色绘制不同的级别。
通过使用FacetGrid
数据框和将形成网格的行,列或色调尺寸的变量名称初始化对象来使用该类。这些变量应为分类变量或离散变量,然后变量每个级别的数据将用于沿该轴的构面。例如,假设我们要检查tips
数据集中午餐和晚餐之间的差异。
g = sns.FacetGrid(tips,col="time")
在此网格上可视化数据的主要方法是使用
FacetGrid.map()
。在数据框中为其提供绘图功能和变量名称以进行绘图。
g = sns.FacetGrid(tips,col="time")
g.map(plt.hist,"tip")#hist条形图
g=sns.FacetGrid(tips,col="sex",hue="smoker")
g.map(plt.scatter,"total_bill","tip",alpha=.7)#散点图,alpha表示透明度
g.add_legend()#多一个说明项
有几个选项可以控制可传递给类构造函数的网格外观。
g=sns.FacetGrid(tips,row="smoker",col="time",margin_titles=True)
g.map(sns.regplot,"size","total_bill",color=".3",fit_reg=False,x_jitter=.1)#fit_reg是否画回归线
通过提供每个构面的高度以及纵横比来设置图形的大小:
g=sns.FacetGrid(tips,col="day",size=4,aspect=.5)
g.map(sns.barplot,"sex","total_bill")
from pandas import Categorical
ordered_days=tips.day.value_counts().index
print(ordered_days)
ordered_days=Categorical(['Thur','Fri','Sat','Sun'])#指定顺序
g=sns.FacetGrid(tips,row="day",row_order=ordered_days,
size=1.7,aspect=4)
g.map(sns.boxplot,"total_bill")
Index(['Sat', 'Sun', 'Thur', 'Fri'], dtype='object')
可以使用将hue变量中的值的名称映射到有效的matplotlib颜色的字典:
pal=dict(Lunch="seagreen",Dinner="gray")#字典,设置颜色
g=sns.FacetGrid(tips,hue="time",palette=pal,size=5)
g.map(plt.scatter,"total_bill","tip",s=50,alpha=.7,linewidth=.5,edgecolor="white")
g.add_legend()
还可以让绘图的其他方面随色调变量的级别而变化,这有助于制作以黑白打印时更易理解的绘图。为此,将一个字典传递到hue_kws,其中key是绘图函数关键字参数的名称,value是关键字值的列表,每个值对应于hue变量级别。
g=sns.FacetGrid(tips,hue="sex",palette="Set1",size=5,hue_kws={"marker":["^","v"]})#marker画出的形状
g.map(plt.scatter,"total_bill","tip",s=100,linewidth=.5,edgecolor="white")
g.add_legend()
使用
FacetGrid.map()
(可以多次调用)绘制绘图后,可能需要调整绘图的某些方面。对象上还有许多方法FacetGrid
可以以较高的抽象水平处理图形。最通用的是FacetGrid.set()
,还有其他一些更专业的方法,例如FacetGrid.set_axis_labels()
,它尊重内部刻面没有轴标签的事实。例如:
with sns.axes_style("white"):
g=sns.FacetGrid(tips,row="sex",col="smoker",margin_titles=True,size=2.5)
g.map(plt.scatter,"total_bill","tip",color="#334488",edgecolor="white",lw=.5)
g.set_axis_labels("Total bill(US Dollars)","Tip")#x,y轴的名字
g.set(xticks=[10,30,50],yticks=[2,6,10])
g.fig.subplots_adjust(wspace=.02,hspace=.02)#各个子图的宽距,长距
# g.fig.subplots_adjust(left=0.125,right=0.9,bottom=0.1,top=0.9,wspace=.02,hspace=.02)#整体的偏移程度
- 绘制成对数据关系
PairGrid
还可以使用相同的图形类型快速绘制一个小子图的网格,以可视化每个子图中的数据。在中PairGrid
,每个行和列都分配给一个不同的变量,因此生成的图显示了数据集中的每个成对关系。这种绘图样式有时被称为“散点图矩阵”,因为这是显示每种关系的最常用方法,但PairGrid
不仅限于散点图。
g=sns.PairGrid(iris)#指定图类别
g.map(plt.scatter)
可以在对角线上绘制不同的函数,以显示每一列中变量的单变量分布。但是请注意,轴刻度不会与此图的计数或密度轴相对应。
g=sns.PairGrid(iris)
g.map_diag(plt.hist)#指定对角线上画什么图
g.map_offdiag(plt.scatter)#指定非对角线上画什么图
使用此图的一种非常常见的方法是通过单独的分类变量为观察结果着色。例如,鸢尾花数据集对三种不同种类的鸢尾花中的每一种都有四个测量值,可以看到它们之间的差异,
g=sns.PairGrid(iris,hue="Species")
g.map_diag(plt.hist)
g.map_offdiag(plt.scatter)
g.add_legend()
默认情况下,使用数据集中的每个数字列,但是如果需要,您可以专注于特定的关系。
g=sns.PairGrid(iris,vars=["Sepal.Length","Sepal.Width"],hue="Species")#只选其中的两个特征
g.map(plt.scatter)
可以使用其他调色板(例如,显示hue变量的顺序),并将关键字参数传递到绘图函数中。
g=sns.PairGrid(tips,hue="size",palette="GnBu_d")#调色板
g.map(plt.scatter,s=50,edgecolor="white")
g.add_legend()
11、热度图绘制
heatmap在特征相关性方面经常使用。
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
np.random.seed(0)
import seaborn as sns
sns.set()
# 设置默认风格
uniform_data=np.random.rand(3,3)
print(uniform_data)
heatmap=sns.heatmap(uniform_data)
可以通过右边的小竖线,看出来该3*3矩阵的数据大概分布规律。
ax=sns.heatmap(uniform_data,vmin=0.2,vmax=0.5)#调色板的取值区间
我们还可以通过center参数设置中间值
normal_data=np.random.randn(3,3)
print(normal_data)
ax=sns.heatmap(normal_data,center=1)#center指定中心值
flights=sns.load_dataset('flights')
flights.head()
# pivot() 可以将dataframe转换为行列式矩阵 并指定每个元素的存储值
flights=flights.pivot("month","year","passengers")
print(flights)
ax=sns.heatmap(flights)
ax=sns.heatmap(flights,annot=True,fmt="d")#fmt指定加载的数据格式,不要用默认的不然会出现乱码
ax=sns.heatmap(flights,linewidths=.5)#添加格
还可以设置绘图板的颜色模式,
ax=sns.heatmap(flights,cmap="YlGnBu")#cmap指定颜色渐变
ax=sns.heatmap(flights,cbar=False)#隐藏调色板
seaborn学习就到这里了,有什么不懂的地方可以在下方留言,一起讨论。