Seaborn是Python基于matplotlib的数据可视化工具。它提供了很多高层封装的函数,帮助数据分析人员快速绘制美观的数据图形,而避免了许多额外的参数配置问题。 本案例中,我们以波士顿房价数据集为例,演示如何使用seaborn绘制常见的图形。包括散点图、柱状图、饼图、直方图、盒图、概率密度图、小提琴图和点对图等。

波士顿房价数据集中每一列数据对应的含义如下表所示:

列名 类型 说明 示例
CRIM Float 犯罪率 0.00632
ZN Float 超过25000地区的居住面积所占比例 18.0
INDUS Float 非零售业的商业用地比例 2.31
CHAS Int 是否被Charles河流穿过(是,取值1;否,取值0) 0
NOX Float 一氧化氮含量 0.538
RM Float 房子的平均屋子数 6.575
AGE Float 早于1940年建立的的住宅比例 65.2
DIS Float 距离五个上班区域的加权平均距离 4.0900
RAD Int 反映到达放射形状的高速路的能力的指标 1
TAX Float 每10000美元的财产税 296
PTRATIO Float 小学生-老师的比例 15.3
B Float 反映黑人比例的指标,B=1000(BK-0.63)^2,BK是黑人的比例 396.90
LSTAT Float 低收入人群的比例 4.98
MEDV Float 自住房屋价格的中位数(单位1000美元) 24.0

1 数据准备

首先我们可以使用pandas将数据文件读取,数据类型为DataFrame。

In [5]:
import pandas as pd
boston = pd.read_csv("./input/boston_house_prices.csv")
boston.head(10)
Out[5]:
CRIM ZN INDUS CHAS NOX RM AGE DIS RAD TAX PTRATIO B LSTAT MEDV
0 0.00632 18.0 2.31 0 0.538 6.575 65.2 4.0900 1 296 15.3 396.90 4.98 24.0
1 0.02731 0.0 7.07 0 0.469 6.421 78.9 4.9671 2 242 17.8 396.90 9.14 21.6
2 0.02729 0.0 7.07 0 0.469 7.185 61.1 4.9671 2 242 17.8 392.83 4.03 34.7
3 0.03237 0.0 2.18 0 0.458 6.998 45.8 6.0622 3 222 18.7 394.63 2.94 33.4
4 0.06905 0.0 2.18 0 0.458 7.147 54.2 6.0622 3 222 18.7 396.90 5.33 36.2
5 0.02985 0.0 2.18 0 0.458 6.430 58.7 6.0622 3 222 18.7 394.12 5.21 28.7
6 0.08829 12.5 7.87 0 0.524 6.012 66.6 5.5605 5 311 15.2 395.60 12.43 22.9
7 0.14455 12.5 7.87 0 0.524 6.172 96.1 5.9505 5 311 15.2 396.90 19.15 27.1
8 0.21124 12.5 7.87 0 0.524 5.631 100.0 6.0821 5 311 15.2 386.63 29.93 16.5
9 0.17004 12.5 7.87 0 0.524 6.004 85.9 6.5921 5 311 15.2 386.71 17.10 18.9
In [3]:
%matplotlib inline
import seaborn as sns

2 散点图

散点图能够同时将两个数值型特征可视化,从散点图中我们可以直观地观察两个特征之间的关系。例如是否存在线性关系等。 seaborn中可以使用 jointplot 函数绘制散点图。jointplot 函数通常由三个参数需要设置,x和y分别代表需要横轴和纵轴显示的特征名称。data为数据,可以为DataFrame类型。例如在房价数据中,我们需要绘制犯罪率(CRIM)与房价(MEDV)之间的散点图,可以使用以下代码:

In [5]:
sns.jointplot(x="CRIM" , y = "MEDV" ,data = boston)
Out[5]:
<seaborn.axisgrid.JointGrid at 0x7f282cc11c10>

从上图可以发现,我们不仅得到了两个特征的散点图,对于每一个单独的特征,jointplot函数默认将其直方图进行了绘制。同时,也将特征之间的皮尔逊相关系数计算出来。皮尔逊相关系数能够用来判断特征之间的线性关系,其取值范围为[-1,1]。取值为0表示两个特征没有相关性。越接近1说明特征之间越存在正相关性。越接近-1表示特征之间越存在负的线性相关性。在我们的上述例子中,皮尔逊相关系数为-0.39,说明犯罪率与房价之间存在一定的负相关性。

我们可以进一步使用 lmplot 方法将两个特征之间的线性回归直线也画出来。

In [7]:
sns.lmplot(x="CRIM" , y = "MEDV" ,data = boston)
Out[7]:
<seaborn.axisgrid.FacetGrid at 0x7f2823142390>

3 直方图

对于连续型特征,我们可以使用直方图来观察特征取值的分布情况。在seaborn中,直方图可以使用 distplot 函数进行绘制。例如,我们绘制出单位财产税(TAX)特征的直方图。

In [9]:
sns.distplot(boston["TAX"]) 
Out[9]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f2841605b90>

distplot 函数默认同时绘制直方图和KDE(核密度图),如果不需要核密度图,可以将kde参数设置成False。

In [10]:
sns.distplot(boston["TAX"], kde = False) 
Out[10]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f2822de9390>

同样,我们可以绘制房间数的直方图。

In [11]:
sns.distplot(boston["RM"], kde = False) 
Out[11]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f2822d97cd0>

可见,房间数近似服从正态分布。我们可以通过bins参数设置分段数量,例如我们观察房价(MEDV)特征,将bins设置成100。

In [14]:
sns.distplot(boston["MEDV"], bins = 100, kde = False) 
Out[14]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f2822ab0d90>

4 盒图

盒图可以直观地将连续型特征的中位数、上下四分位数显示出来。通常也作为一种单特征离群值检测的定性方法。在seaborn中,可以使用 boxplot 函数绘制盒图。参数orient设置盒图的朝向。

In [15]:
sns.boxplot(boston["MEDV"],orient = "v")
Out[15]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f28227b4f90>

我们可以先对数据进行分组,然后对比不同组数据的分布(盒图表示)。我们只需要给 boxplot 函数制定x和y两个参数。其中,x为分组特征,需要为离散型。y为对比的特征。例如我们查看不同的房间数下,房价的分布情况,可以使用以下代码:

In [16]:
import math
boston["RM_int"] = boston["RM"].map(math.floor) #因为RM原始为连续型特征,首先对其取整
sns.boxplot(x="RM_int", y = "MEDV",data = boston, orient="v")
Out[16]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f282269ff50>

通过上图可以看出,随着房间数目的增大,房价呈现先下降后上升的变化趋势。

进一步地,我们可以通过hue参数制定第二个分组特征。例如我们希望进一步观察房子是否在河边(CHAS)对房价的影响。

In [17]:
sns.boxplot(x="RM_int", y = "MEDV", hue = "CHAS",data = boston, orient="v")
Out[17]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f28223d1b50>

通过上述盒图,我们可以得出两个基本观察结论。首先,房间数小于5的房子都不在河边。其次,在房间数量相同的情况下,河边的房子比非河边的房子价格要高。以上两点与我们日常生活经验也是相符合的。

5 柱状图

对于离散型特征,我们可以使用柱状图绘制其每一种取值的样本数量。例如,对于房间数(RM_int),可以通过seaborn的 countplot 函数画出不同房间数量的房子的数量。

In [19]:
sns.countplot(x = "RM_int", data = boston)
Out[19]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f282264b610>

同样地,我们可以进一步制定一个分组特征绘制不同分组下的柱状图。

In [20]:
sns.countplot(x = "RM_int", hue = "CHAS", data = boston)
Out[20]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f2822148090>

6 核密度图

与直方图类似,核密度图也是一种研究特征分布的工具。在seaborn中,通过 kdeplot 函数绘制核密度图。

In [21]:
sns.kdeplot(boston["CRIM"])
Out[21]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f2822091f10>
In [22]:
sns.kdeplot(boston["ZN"])
Out[22]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f2821f89290>

我们可以绘制两个特征的核密度图。例如,绘制一氧化碳和低收入人群占比两个特征的核密度图。

In [23]:
sns.kdeplot(boston["NOX"], boston["LSTAT"])
/explorer/pyenv/jupyter/lib/python2.7/site-packages/numpy/ma/core.py:6385: MaskedArrayFutureWarning: In the future the default for ma.minimum.reduce will be axis=0, not the current None, to match np.minimum.reduce. Explicitly pass 0 or None to silence this warning.
  return self.reduce(a)
/explorer/pyenv/jupyter/lib/python2.7/site-packages/numpy/ma/core.py:6385: MaskedArrayFutureWarning: In the future the default for ma.maximum.reduce will be axis=0, not the current None, to match np.maximum.reduce. Explicitly pass 0 or None to silence this warning.
  return self.reduce(a)
Out[23]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f2821ef54d0>

7 小提琴图

核密度图是一种结合了盒图和核密度图的图。它将盒图和密度图展示在同一个图上,因长相通常类似小提琴而得名。在seaborn中,可以使用 violinplot 函数绘制小提琴图。

In [24]:
sns.violinplot(x="RM_int", y = "MEDV",data = boston)
Out[24]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f2821eced10>

与盒图类似,我们可以在小提琴图中制定额外的分组特征。

In [25]:
sns.violinplot(x="RM_int", y = "MEDV", hue = "CHAS",data = boston, orient="v")
Out[25]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f28207e0d50>

将上图的分组分别绘制在盒图的两边, 使用split=True参数设置。

In [26]:
sns.violinplot(x="RM_int", y = "MEDV", hue = "CHAS",split = True, data = boston)
Out[26]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f28205fb750>

8 点对图

点对图可以同时将多个特征两两之间的散点图等通过一条命令进行绘制。点对图的绘制函数为 pairplot。为了显示美观,我们只选取数据找那个特征的一个子集进行绘制。

In [27]:
sns.pairplot(boston[["CRIM","NOX","RM","LSTAT","MEDV"]])
Out[27]:
<seaborn.axisgrid.PairGrid at 0x7f282264b650>