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()
sns.set()

四种预设,按相对尺寸的顺序(线条越来越粗),分别是paper,notebook, talk, and poster。notebook的样式是默认的,上面的绘图都是使用默认的notebook预设。

  • paper
  • sns.set()
    sns.set_context("paper")#别名
    plt.figure(figsize=(8,6))
    sinplot()
    通过更改context还可以独立地扩展字体元素的大小。(
    
    sns.set_context("notebook",font_scale=1.5,rc={"lines.linewidth":3.5})#font_scale:字体大小
    sinplot()
    2、圆形彩色系统
    当你有六个以上的分类要区分时,最简单的方法就是在一个圆形的颜色空间中画出均匀间隔的颜色(这样的色调会保持亮度和饱和度不变)。这是大多数的当他们需要使用比当前默认颜色循环中设置的颜色更多时的默认方案。
    最常用的方法是使用hls的颜色空间,这是RGB值的一个简单转换

    sns.palplot(sns.color_palette("hls",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)
    
  • cubehelix_palette()调色板
    色调线性变换
    所述cubehelix调色板系统使得与亮度的线性增加或减小,在色调的一些变化顺序调色板。这意味着当转换为黑白(用于打印)或色盲人员查看时,色图中的信息将保留。
  • sns.palplot(sns.color_palette("cubehelix",8))
    
    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)#从里到外,由浅入深
    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曲线(和核密度有关,这里不讲)
    根据均值和协方差生成数据

    mean,cov=[0,1],[(1,.5),(.5,1)]
    data=np.random.multivariate_normal(mean,cov,200)
    df=pd.DataFrame(data,columns=["x","y"])
    观测两个变量之间的分布关系最好用散点图,可视化双变量分布的最熟悉的方法是散点图,其中每个观察点的点均位于xy值处。这与二维的地毯图相似。可以使用matplotlib plt.scatter函数绘制散点图,这也是该jointplot()函数显示的默认图样:
    
    sns.jointplot(x="x",y="y",data=df)#散点图
    直方图的双变量类似物称为“六边形”图,因为它显示了落在六边形箱中的观测值。此图最适合于相对较大的数据集。可通过matplotlib plt.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()
    第二种方法是使用防止重叠的算法沿分类轴调整点。尽管它仅适用于相对较小的数据集,但它可以更好地表示观测值的分布。这种情节有时也被称为“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)
    组合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表示透明度
    
    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=["-","--"])#制定颜色、线条、标志
    

    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)

    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最多可以被吸引到三个维度:rowcol,和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()#多一个说明项
    
    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')

    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,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()
    
    # pivot() 可以将dataframe转换为行列式矩阵 并指定每个元素的存储值
    flights=flights.pivot("month","year","passengers")
    print(flights)
    ax=sns.heatmap(flights)