可视化数据的分布
Matplotlib虽然已经是比较优秀的绘图库了,但是它有一个令人头疼的问题,那就是API使用过于复杂,它里面有上千个函数和参数,属于典型的那种可以用它做任何事,却又无从下手。
Seaborn基于Matplotlib核心库进行了更高级的API封装,可以轻松地画出更漂亮的图形,而Seaborn的漂亮主要体现在配色更加舒服,以及图形元素的样式更加细腻。不过,使用Seaborn绘制图表之前,需要导入绘图的接口,具体代码如下。
import seaborn as sns
另外,也可以在Jupyter Notebook中使用如下魔术命令绘图。
%matplotlib inline
当处理一组数据时,通常先要做的就是了解变量是如何分布的。对于单变量的数据来说,采用直方图或核密度曲线是个不错的选择,对于双变量来说,可采用多面板图形展现,比如散点图、二维直方图、核密度估计图形等。针对这种情况,Seaborn库提供了对单变量和双变量分布的绘制函数,如displot()函数、jointplot()函数,下面具体来介绍这些函数的使用,具体内容如下。
一、 绘制单变量分布
要想描述单变量的分布情况,可以采用最简单的直方图进行展现。Seaborn中提供了一个distplot()函数,它默认绘制的是一个带有核密度估计曲线的直方图。distplot()函数的语法格式如下。
seaborn.distplot(a, bins = None,hist = True,kde = True,rug = False,fit = None,
hist_kws = None,kde_kws = None,rug_kws = None,fit_kws = None,
color = None,vertical = False,norm_hist = False,axlabel = None,
label = None,ax = None)
上述函数中常用参数的含义如下:
(1) a:表示要观察的数据,可以是Series、一维数组或列表。
(2) bins:用于控制条形的数量。
(3) hist:接收布尔类型,表示是否绘制(标注)直方图。
(4) kde:接收布尔类型,表示是否绘制高斯核密度估计曲线。
(5) rug:接收布尔类型,表示是否在支持的轴方向上绘制rugplot。
通过distplot()函数绘制直方图的示例如下。
In [14]: import numpy as np
sns.set() # 显式调用set()获取默认绘图
np.random.seed(0) # 确定随机数生成器的种子
arr = np.random.randn(100) # 生成随机数组
ax = sns.distplot(arr, bins=10) # 绘制直方图
上述示例中,首先导入了用于生成数组的numpy库,然后使用seaborn调用set()函数获取默认绘图,并且调用random模块的seed()函数确定随机数生成器的种子,保证每次产生的随机数是一样的,接着调用randn()函数生成包含100个随机数的数组,最后调用distplot()函数绘制直方图。
运行结果如图1所示。
图1 运行结果
从图1中看出,直方图共有10个条柱,每个条柱的颜色为蓝色,并且有核密度估计曲线。根据条柱的高度可知,位于-1~1区间的随机数值偏多,小于-2的随机数值偏少。
注意:
如果希望使用Seaborn用Matplotlib的默认样式,之前可以通过从Seaborn库中导入apionly模块解决这个问题,但是现在已经弃用了(自2017年7月起)。因此,现在导入Seaborn时,需要显式地调用set()或set_style()、set_context()和set_palette()中的一个或多个函数,以获取Seaborn或者Matplotlib默认的绘图样式。
通常,采用直方图可以比较直观地展现样本数据的分布情况,不过,直方图存在一些问题,它会因为条柱数量的不同导致直方图的效果有很大的差异。为了解决这个问题,可以绘制核密度估计曲线进行展现。
核密度估计是在概率论中用来估计未知的密度函数,属于非参数检验方法之一,可以比较直观的看出数据样本本身的分布特征。
通过distplot()函数绘制核密度估计曲线的示例如下。
In [15]: # 创建包含500个位于[0,100]之间的随机整数数组
array_random = np.random.randint(0, 100, 500)
# 绘制核密度估计曲线
sns.distplot(array_random, hist=False, rug=True)
Out[15]: <matplotlib.axes._subplots.AxesSubplot at 0xbe33588>
上述示例中,首先通过random.randint()函数返回一个最小值不低于0、最大值不高于100的500个随机整数数组,然后调用distplot()函数绘制核密度估计曲线。
运行结果如图2所示。
图2 运行结果
从图2中看出,图表中有一条核密度估计曲线,并且在x轴的上方生成了观测数值的小细条。
除了使用displot()函数之外,还可以使用kdeplot()函数拟合并绘制核密度估计曲线,大家可以参阅官方文档进行深入学习,这里就不再过多赘述了。
二、 绘制双变量分布
两个变量的二元分布可视化也很有用。在Seaborn中最简单的方法是使用jointplot()函数,该函数可以创建一个多面板图形,比如散点图、二维直方图、核密度估计等,以显示两个变量之间的双变量关系及每个变量在单独坐标轴上的单变量分布。
jointplot()函数的语法格式如下。
seaborn.jointplot(x, y, data=None, kind='scatter', stat_func=<function pearsonr>,
color=None, size=6, ratio=5, space=0.2, dropna=True, xlim=None,
ylim=None, joint_kws=None, marginal_kws=None, annot_kws=None, **kwargs)
上述函数中常用参数的含义如下:
(1) kind:表示绘制图形的类型。
(2) stat_func:函数用于计算有关关系的统计量并标注图。
(3) color:表示绘图元素的颜色。
(4) size:用于设置图的大小(正方形)。
(5) ratio:表示中心图与侧边图的比例。若该参数的值越大,则中心图的占比会越大。
(6) space:用于设置中心图与侧边图的间隔大小。
(7) xlim,ylim:表示x、y轴的范围。
下面以散点图、二维直方图、核密度估计曲线为例,为大家介绍如何使用Seaborn绘制这些图形。
- 绘制散点图
调用seaborn.jointplot()函数绘制散点图的示例如下。
In [16]: # 创建DataFrame对象
dataframe_obj = pd.DataFrame({"x": np.random.randn(500),
"y": np.random.randn(500)})
# 绘制散布图
sns.jointplot(x="x", y="y", data=dataframe_obj)
Out[16]: <seaborn.axisgrid.JointGrid at 0xcaea240>
上述示例中,首先创建了一个DataFrame对象dataframe_obj作为散点图的数据,其中x轴和y轴的数据均为500个随机数,接着调用jointplot()函数绘制一个散点图,散点图x轴的名称为“x”,y轴的名称为“y”。
运行结果如图3所示。
图3 运行结果
从图3中看出,散点图的底部显示了计算的两个系数:pearsonr和p,另外在图表的上方和右侧增加了直方图,便于观察x和y轴数据的整体分布情况,并且它们的均值都是0。
- 绘制二维直方图
二维直方图类似于“六边形”图,主要是因为它显示了落在六角形区域内的观察值的计数,适用于较大的数据集。当调用jointplot()函数时只要传入kind="hex",就可以绘制二维直方图,具体示例代码如下。
In [17]: # 绘制二维直方图
sns.jointplot(x="x", y="y", data=dataframe_obj, kind="hex")
Out[17]: <seaborn.axisgrid.JointGrid at 0xc274da0>
运行结果如图4所示。
图4 运行结果
从六边形颜色的深浅,可以观察到数据密集的程度,另外图形的上方和右侧仍然给出了直方图。注意,在绘制二维直方图时,最好使用白色背景。
- 绘制核密度估计图形
利用核密度估计同样可以查看二元分布,Seaborn中用等高线图来表示。当调用jointplot()函数时只要传入kind="kde",就可以绘制核密度估计图形,具体示例代码如下。
In [18]: # 核密度估计
sns.jointplot(x="x", y="y", data=dataframe_obj, kind="kde")
Out[18]: <seaborn.axisgrid.JointGrid at 0xcdf5588>
上述示例中,绘制了核密度的等高线图,另外在图形的上方和右侧给出了核密度曲线图。
运行结果如图5所示。
图5 运行结果
通过观察等高线的颜色深浅,可以看出哪个范围的数值分布的最多,哪个范围的数值分布的最少。
三、 绘制成对的双变量分布
要想在数据集中绘制多个成对的双变量分布,则可以使用pairplot()函数实现,该函数会创建一个坐标轴矩阵,并且显示DataFrame对象中每对变量的关系。另外,pairplot()函数也可以绘制每个变量在对角轴上的单变量分布。
接下来,通过sns.pairplot()函数绘制数据集变量间关系的图形,示例代码如下。
In [19]: # 加载seaborn中的数据集
dataset = sns.load_dataset("tips")
# 绘制多个成对的双变量分布
sns.pairplot(dataset)
Out[19]: <seaborn.axisgrid.PairGrid at 0xd3b26d8>
上述示例中,通过load_dataset()函数加载了seaborn中内置的数据集(点击链接 https://github.com/mwaskom/seaborn-data
可以查看内置的所有数据集),根据tips数据集绘制多个双变量分布。
运行结果如图6所示。
图6 运行结果