做者|Bex Tuychiev
编译|VK
来源|Towards Datas Sciencehtml
本文的目标是让你对使用Seaborn的relplot()函数绘制统计图有必定的了解。node
当我开始学习数据可视化时,我第一次被介绍到Matplotlib。它是一个如此巨大的库,你几乎能够看到任何与数据相关的东西。正是这种广阔的空间,令人们可以以多种方式创造一个单一的图表。python
虽然它的灵活性对于经验丰富的科学家来讲是理想的,但做为一个初学者,要区分这些方法之间的代码对我来讲简直是一场噩梦。做为一名程序员,我甚至考虑过使用Tableau的无代码接口,这一点我深感羞愧。我想要一个易于使用的东西,同时,使我可以建立那些其余人(在代码中)正在制做的酷图。git
我在学生阶段了解了Seaborn,最后找到了个人选择。我对数据可视化的黄金法则理解是“若是你能在Seaborn作的话,就在Seaborn作”。它比其对应的Matplotlib提供了许多优点。程序员
首先,它很是容易使用。只需几行代码就能够建立复杂的绘图,而且使用内置样式仍然可使其看起来很漂亮。其次,它与Pandas数据帧配合得很是好,这正是做为数据科学家所须要的。github
最后但并不是最不重要的是,它构建在Matplotlib自己之上。这意味着你将享受Mpl提供的大部分灵活性,同时仍将代码语法保持在最低限度。shell
Seaborn将其全部API分为三类:绘制统计关系、可视化数据分布和分类数据绘图。Seaborn提供了三个高级函数,它们包含了它的大部分特征,其中之一是relplot()。机器学习
relplot()能够可视化定量变量之间的任何统计关系。在本文中,咱们将介绍这个函数的几乎全部特性,包括如何建立子图等等。函数
获取此GitHub repo上文章的notebook和示例数据:https://github.com/BexTuychiev/medium_stories/tree/master/learn_one_third_of_seaborn_relplot工具
# 加载必要的库 import pandas as pd import matplotlib.pyplot as plt import seaborn as sns import numpy as np # 绘制漂亮的图形,避免模糊的图像 %config InlineBackend.figure_format = 'retina' # 设置环境 sns.set_context('notebook') # 忽略警告 import warnings warnings.filterwarnings('ignore') # 启用多个单元输出 from IPython.core.interactiveshell import InteractiveShell InteractiveShell.ast_node_interactivity = 'all'
咱们以sns的缩写导入Seaborn。你可能一直在想,为何它不被缩写为sb。好吧,看看这个:它的别名来自电视剧《The West Wing》中的一个虚构人物Samuel Norman Seaborn。这是一个开玩笑的首字母缩写。
对于示例数据,我将使用Seaborn的一个内置数据集和一个我从Kaggle下载的数据集。你能够经过这个连接获得它:https://www.kaggle.com/dgawlik/nyse/download
# 加载示例数据 cars = sns.load_dataset('mpg') stocks = pd.read_csv('data/prices-split-adjusted.csv', parse_dates=['date'], index_col=0)
第一个数据集是关于汽车的数据,包括发动机、车型等。第二个数据集提供了500多家公司的纽约股票价格信息。
cars.head() cars.info() cars.describe()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 398 entries, 0 to 397 Data columns (total 9 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 mpg 398 non-null float64 1 cylinders 398 non-null int64 2 displacement 398 non-null float64 3 horsepower 392 non-null float64 4 weight 398 non-null int64 5 acceleration 398 non-null float64 6 model_year 398 non-null int64 7 origin 398 non-null object 8 name 398 non-null object dtypes: float64(4), int64(3), object(2) memory usage: 28.1+ KB
stocks.head() stocks.info()
<class 'pandas.core.frame.DataFrame'> DatetimeIndex: 851264 entries, 2016-01-05 to 2016-12-30 Data columns (total 6 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 symbol 851264 non-null object 1 open 851264 non-null float64 2 close 851264 non-null float64 3 low 851264 non-null float64 4 high 851264 non-null float64 5 volume 851264 non-null float64 dtypes: float64(5), object(1) memory usage: 45.5+ MB
两个数据集中都有一些空值。咱们目的是演示,咱们就能够放心的丢弃它们。
cars.dropna(inplace=True) stocks.dropna(inplace=True)
专业提示:让你的数据集尽量的整洁,这样Seaborn才能表现出色。确保每一行都是一个观察值,每一列都是一个变量。
relplot
绘散点图让咱们从散点图开始。散点图是用来找出变量之间的模式和关系的最好和最普遍使用的图之一。
这些变量一般是定量的,例如测量值、一天中的温度或任何数值。散点图将x和y值的每一个元组可视化为一个点,而且该图将造成一个点云。这些类型的图是人眼探测模式和关系的理想选择。
你可使用sb(我将从如今开始缩写为sb)的内置scatterplot()函数建立散点图。可是这个函数缺乏relplot()中版本所提供的灵活性。让咱们看一个使用relplot()的示例。
利用汽车数据集,咱们想知道重型汽车是否具备更大的马力。因为这两个特征都是数值型的,咱们可使用散点图:
sns.relplot(x='weight', y='horsepower', data=cars, kind='scatter');
函数具备参数x、y和data参数,分别指定要在X、Y轴上绘制的值以及它应该使用的数据。咱们使用kind参数指定它应该使用散点图。实际上,默认状况下,它被设置为scatter。
从图表来看,能够解释为较重的汽车确实有更大的马力。很明显,还有更多的汽车重量在1500到3000之间,马力50-110。
在前面的图的基础上,如今咱们还想添加一个新变量。让咱们看看重车是否有更大的排量(他们能储存多少燃料)。理想状况下,咱们但愿将此变量绘制为点的大小:
sns.relplot(x='weight', y='horsepower', data=cars, kind='scatter', size='displacement');
使用size参数来改变相对于第三个变量的点大小。只需将列名做为字符串传递,就能够进行设置,就像咱们的示例中同样。此图显示了重量和发动机尺寸之间的明确关系。可是,你能够在中心看到一些不符合趋势的点。
重要的是传递一个数值变量,它将具备较少的“值周期”。若是太多的话,你的眼睛会很难理解这些事情。若是咱们用第三个变量weight建立上面的图,你能够看到:
sns.relplot(x='displacement', y='horsepower', data=cars, kind='scatter', size='weight');
正如你所见,趋势并不明显,很难区分大小。
也能够将颜色标记用于散点图中的第三个变量。它也很是简单,就像点大小同样。假设咱们还想将加速度(汽车达到60英里/小时(秒)的时间)编码为点颜色:
sns.relplot(x='weight', y='horsepower', data=cars, kind='scatter', size='displacement', hue='acceleration');
从图中,咱们能够看到数据集中一些速度最快的汽车(较暗的点)马力较低,但重量也较轻。注意,咱们使用hue参数来编码颜色。颜色根据传递给此参数的变量类型而变化。若是咱们传递origin列,它是一个范畴变量,那么它将有三个颜色标记,而不是一个连续的(从亮到暗)色调:
sns.relplot(x='weight', y='horsepower', data=cars, kind='scatter', size='displacement', hue='origin');
专业提示:注意输入到hue参数的变量类型。类型能够彻底更改结果。
若是你不喜欢默认调色板(默认状况下很是好),能够轻松自定义:
sns.relplot(x='weight', y='horsepower', data=cars, kind='scatter', size='displacement', hue='acceleration', palette='crest');
将palette参数设置为你本身的颜色映射。可在此处找到可用选项板的列表:http://seaborn.pydata.org/tutorial/color_palettes.html
让咱们回到第一个图。咱们绘制了重量与马力的散点图。如今,让咱们添加origin列做为第三个变量:
sns.relplot(x='weight', y='horsepower', data=cars, hue='origin');
虽然颜色在这张图中增长了一层额外的信息,但在更大的数据集中,可能很难区分点群中的颜色。为了更清晰起见,咱们将点的样式添加到绘图中:
sns.relplot(x='weight', y='horsepower', data=cars, hue='origin', style='origin');
好一点了。改变点的样式和颜色是很是有效的。若是咱们只使用点的样式来指定原点,看看会发生什么:
sns.relplot(x='weight', y='horsepower', data=cars, style='origin');
提示:将色调和样式参数结合使用,可使绘图更加清晰。
咱们去掉了色调的参数,这使得咱们的图表更难理解。若是不喜欢默认颜色,你能够更改:
首先,你应该建立一个字典,将各个颜色映射到每一个类别。请注意,该字典的键应该与图例中的名称相同。
hue_colors = {'usa': 'red', 'japan': 'orange', 'europe': 'green'} sns.relplot(x='weight', y='horsepower', data=cars, hue='origin', style='origin', palette=hue_colors);
从图中能够看出,咱们数据集中的大部分汽车都来自美国。
让咱们再次回到咱们的第一个例子。让咱们再画一次,但要增长一点透明度:
sns.relplot(x='weight', y='horsepower', data=cars, alpha=0.6);
咱们使用alpha参数来设置点的透明度。它接受0到1之间的值。0是彻底透明的,1是彻底不透明的。当你有一个大的数据集而且你想找出图中的簇或组时,它是一个很是有用的特性。下降透明度时,图中有许多圆点的部分将变暗。
在Seaborn也可使用子图。我之因此使用relplot()而不是scatterplot(),由于它不能建立一个子图。
因为relplot是一个图形级别的函数,它生成一个FacetGrid(一个由多个绘图组成的网格)对象,而scatterplot()只打印到一个matplotlib.pyplot.Axes(单个绘图)不能转换为子图的对象:
fg = sns.relplot() print(type(fg)) plot = sns.scatterplot() print(type(plot)) <class 'seaborn.axisgrid.FacetGrid'> <class 'matplotlib.axes._subplots.AxesSubplot'>
让咱们看一个例子,咱们想在其中使用子图。在上面的其中一个图中,咱们将4个变量编码到一个单独的图中(重量,马力,排量和加速度)。如今,咱们还要添加汽车的原产地。为了使信息更易于解释,咱们应该将其划分为子图:
sns.relplot(x='weight', y='horsepower', data=cars, kind='scatter', size='displacement', hue='acceleration', palette='crest', col='origin');
这一次,咱们添加了一个新参数col,指出咱们但愿在列中建立子图。这些类型的子区间很是有用,由于如今很容易看到第五个变量的趋势。顺便说一句,传递给col的变量应该是离散的,这样才能起做用。此外,SB在一行中显示列。若是有多个类别须要绘制,咱们不但愿这样。让咱们看一个使用咱们的数据的用例,尽管它的类别较少:
sns.relplot(x='weight', y='horsepower', data=cars, kind='scatter', size='displacement', hue='acceleration', palette='crest', col='origin', col_wrap=2);
col_wra参数告诉SB咱们但愿一行中有多少列。
还能够指定列中类别的顺序:
sns.relplot(x='weight', y='horsepower', data=cars, kind='scatter', size='displacement', hue='acceleration', palette='crest', col='origin', col_order=['japan', 'europe', 'usa']);
也能够在行中显示相同的信息:
sns.relplot(x='weight', y='horsepower', data=cars, kind='scatter', size='displacement', hue='acceleration', palette='crest', row='origin');
若是有不少类别,那么使用行并非颇有用,最好仍是坚持使用列。你能够再次使用row_order指定行的顺序。
关系图的另外一种常见类型是线图。而在散点图中,每一个点都是一个独立的观察点,在线图中,咱们绘制了一个变量和一些连续变量,一般是一段时间。咱们的第二个样本数据集包含2010年至2016年跟踪的501家公司的纽约证券交易所数据。
为了便于说明,让咱们观察给定时间段内全部公司的收盘价。因为涉及日期,所以线条图是此任务的最佳视觉类型:
专业提示:若是数据集中有一个日期列,请将其设置为日期类型,而后使用set_index()函数将其设置为索引。或使用pd.read_csv(parse_dates=['date_column'], index_col='date_column')。它将容许你绘制线图,并使日期的设置更容易。
对于线图,咱们再次使用relplot()并将kind设置为line。这将绘制第二个连续变量(一般是时间)上跟踪的单个变量。
sns.relplot(x=stocks.index, y='close', data=stocks, kind='line');
咱们能够看到明显的趋势。全部公司的股票在给定的时间段内都在增加。蓝色较深的线表明6年来追踪的全部公司收盘价的平均值。
SB会自动增长一个置信区间,若是对一个点有多个观测会添加那条线周围的阴影区域,稍后会详细介绍。如今,让咱们把数据集中到3家公司:
am_ap_go = stocks[stocks['symbol'].isin(['AMZN', 'AAPL', 'GOOGL'])] am_ap_go.shape (5286, 6)
如今,让咱们经过将数据分组到三个公司来从新建立上面的线图。这将在同一绘图中建立三条线,而不是一条:
sns.relplot(x=am_ap_go.index, y='close', data=am_ap_go, kind='line', hue='symbol');
就像咱们在散点图示例中所作的那样,咱们使用hue参数在数据中建立子组。一样,你必须将一个范畴变量传递到hue中。在这幅图中,咱们能够看到,在2016年以后,亚马逊和谷歌的股价很是接近,而苹果在整个期间都处于底部。如今,让咱们看看咱们是如何将每一行与颜色区分开来的:
咱们使用style参数来指定每一行须要不一样的线条样式:
sns.relplot(x=am_ap_go.index, y='close', data=am_ap_go, kind='line', hue='symbol', style='symbol');
好吧,这可能不是不一样线条风格的最佳例子,由于观察是针对每一天的,并且很是紧凑。让咱们仅对2015-2016年期间进行子集划分,并绘制相同的线图:
am_ap_go_subset = am_ap_go.loc['2015-01-01':'2015-12-31'] sns.relplot(x=am_ap_go_subset.index, y='close', data=am_ap_go_subset, kind='line', hue='symbol', style='symbol');
如今线条风格更清晰了。你可能会说,这好像没什么分别。可是当你有一个图表,它的线很是紧凑的话,这可能能够帮助你理解某些东西。
当你有一个较小的数据集而且想要建立一个线图时,用点标记来标记每一个数据点可能会颇有用。对于咱们较小的股票价格分布数据来讲仍然是很是紧张的。因此,让咱们用一个更小的时间段,来看看如何使用点标记:
smaller_subset = am_ap_go_subset.loc["2015-01-01":"2015-03-01"] sns.relplot(x=smaller_subset.index, y='close', data=smaller_subset, kind='line', hue='symbol', style='symbol', markers=True) plt.xticks(rotation=60);
如今每行都有不一样的标记。咱们将markers参数设置为True以激活此功能。
接下来,咱们将探讨在SB中计算线图的置信区间。若是对一个点有多个观测值,则会自动添加置信区间。
在咱们对这三家公司的数据中,每一天都有三个观察结果:一个是亚马逊,一个是谷歌,一个是苹果。当咱们建立不带子组(不带色调参数)的线条图时,默认状况下,SB取这三个值的平均值:
sns.relplot(x=am_ap_go.index, y='close', data=am_ap_go, kind='line');
较暗的线表示这三家公司股价的平均值。阴影区域为95%置信区间。这是很是巨大的,由于咱们的样本数据只有三家公司。阴影区意味着95%的人的平均值在这个区间内。它代表了咱们数据的不肯定性。
例如,2017年,人口平均数在100到800之间。置信区间的范围是巨大的。将ci参数设置为“None”能够关闭置信区间:
sns.relplot(x=am_ap_go.index, y='close', data=am_ap_go, kind='line', ci=None);
或者,若是须要,能够显示标准误差而不是置信区间。将ci参数设置为sd:
sns.relplot(x=am_ap_go.index, y='close', data=am_ap_go, kind='line', ci='sd');
也许这些参数对于咱们的示例数据不是颇有用,可是当你处理大量真实数据时,它们将很是重要。
最后一点:若是要为线图建立子图,可使用相同的col和row参数。
最后,咱们完成了Seaborn的关系图。线图和散点图是在数据海洋中发现洞察力和趋势的很是重要的视觉辅助工具。所以,掌握它们是很重要的。尽量使用Seaborn来建立它们。
欢迎关注磐创AI博客站:
http://panchuang.net/
sklearn机器学习中文官方文档:
http://sklearn123.com/
欢迎关注磐创博客资源汇总站:
http://docs.panchuang.net/