目的:本来想看一下lineplot的其他参数是什么意思,在网上找了一些文章,基本都只是介绍了一部分,或者对errorbar的介绍不太满意,想着这东西本身也不是很难,参数也没有那么多,索性自己对照官网和一些文章,写一篇,把lineplot(scatterplot),relplot的所有参数都以案例可视化写出来:
内容:1.基本介绍 2.所有参数(按相关性顺序写) 3.重点介绍errorbar和bootstrap自助法 4.relplot的不同之处
一、是什么
relplot,即relationnal plot的缩写,关系型图表,内含scatterplot和lineplot两类,即散点图和折线图。
如果要画散点图,用relplot(kind='scatter'),默认是散点图,或者直接sns.scatterplot()
如果要画折线图,用relplot(kind='line'),或者直接sns.lineplot()
relplot,lineplot,scatterplot,这三个参数大部分是一样,知道一个则三个都略懂。
官网链接:https://seaborn.pydata.org/generated/seaborn.relplot.html
当然是全英文的,如果英语不错,建议直接阅读,英语忘了,往下看。
seaborn.relplot(data=None,*,x=None,y=None,hue=None,size=None,style=None,units=None,row=None,col=None,col_wrap=None,row_order=None,col_order=None,palette=None,hue_order=None,hue_norm=None,sizes=None,size_order=None,size_norm=None,markers=None,dashes=None,style_order=None,legend='auto',kind='scatter',height=5,aspect=1,facet_kws=None,**kwargs)
seaborn.lineplot(data=None,*,x=None,y=None,hue=None,size=None,style=None,units=None,palette=None,hue_order=None,hue_norm=None,sizes=None,size_order=None,size_norm=None,dashes=True,markers=None,style_order=None,estimator='mean',errorbar=('ci',95),n_boot=1000,seed=None,orient='x',sort=True,err_style='band',err_kws=None,legend='auto',ci='deprecated',ax=None,**kwargs)
scatterplot和lineplot参数几乎完全一样。
二、参数案例详解
不完全按照官网顺序解读,按照自己的理解和参数相关性,挨个解释:
使用jupyter notebook,用容易搞到的数据演示,seaborn有自带的数据集,由于某些原因,国内无法获取到,除非科学或者去其他网站下载,国内下载地址:
微信扫个码就可以免费下载5个/天。
import numpy as np
import pandas as pd
from sklearn.model_selection import cross_val_score, train_test_split,GridSearchCV, RandomizedSearchCV
from sklearn.metrics import r2_score,auc
import lightgbm as lgb
from sklearn import datasets
import matplotlib.pyplot as plt
import seaborn as sns
import notebook
notebook.__version__
版本:'6.5.4'
tips = pd.read_csv("C:/Users/Administrator/Downloads/tips.csv")
tips
先解释一下这个数据集,记录了客人给小费的情况,total_bill是这顿吃了多少钱,tip是给了多少小费,sex是顾客性别,也可能是给小费的那个顾客的性别,smoke是否吸烟,day是周几,time是吃的午饭还是晚饭,size是这桌有多少人。查看数据情况,244行,没有缺失值,一桌最低吃3块,最高吃50块,小费最低1块,最高10块,吃饭人数最低1人最多6人,只有午饭、晚饭之分,周几只有四五六日。
# 查看各列的唯一值
tips.time.unique(),tips.day.unique(),tips['size'].unique(),tips.sex.unique(),tips.smoker.unique()
(array(['Dinner', 'Lunch'], dtype=object),
array(['Sun', 'Sat', 'Thur', 'Fri'], dtype=object),
array([2, 3, 4, 1, 6, 5], dtype=int64),
array(['Female', 'Male'], dtype=object),
array(['No', 'Yes'], dtype=object))
先把数据丢进去,看看SNS会怎画图。
2.1 data,建议传,pandas.DataFrame,numpy.ndarray, mapping, or sequence
如果传的是df,不指定x,y,则会以index为横轴,列数值为Y轴
如果你硬是不想传data,那就把后面的x=,y=要传进去。
sns.relplot(kind='line',data=tips)
# sns.lineplot(data=tips)
可知,会把数值型的数据,全给画上去。
2.2 x,y,一般绘图,都是想好了哪个是X轴哪个是Y轴,所以基本上x,y都要传,除非数据极其简单,一个index少数几个数值列,那只传个data也行。如果data传入了,一般的x='列名'或者index,y='列名'即可,如果你data没传,x和y必须传一组数据。
2.3 hue,将数据以不同颜色的线、点分组,此案例中hue='sex',当hue=数值型,会以分位数的形式表示。
2.4.style, style='sex'以不同的线形状、点的标记形状分组,建议传类别列,强传数值型也行,不推荐,可以搭配hue一起,这样两种类别,颜色不同,标记形状也不同,比较好看。
2.5 size,以粗细不同的线,大小不同的点分组,可传类别、数值型
plt.rcParams['font.sans-serif'] = ['SimHei'] # 中文字体设置-黑体
fig,(ax1,ax2,ax3)=plt.subplots(1,3,figsize=(12,6))
# 第一个图
sns.scatterplot(data=tips,x='total_bill',y='tip'
,ax=ax1,hue='sex')
ax1.set_title('设置hue用颜色区分')
# 第二个图
sns.scatterplot(data=tips,x='total_bill',y='tip'
,ax=ax2,style='sex')
ax2.set_title('设置style用不同标记区分')
# 第三个图
sns.scatterplot(data=tips,x='total_bill',y='tip'
,ax=ax3,size='sex')
ax3.set_title('设置size用大小进行区分')
# 虽然出图了,但是效果还是略显一般,将代码稍加完善
# 所用参数,后面会挨个解释
fig,(ax1,ax2,ax3)=plt.subplots(1,3,figsize=(12,6))
# 第一个图
sns.scatterplot(data=tips,x='total_bill',y='tip'
,ax=ax1,hue='sex')
ax1.set_title('初级阶段')
# 第二个图
sns.scatterplot(data=tips,x='total_bill',y='tip'
,ax=ax2 # 指定子图坐标轴
,style='sex', # 用不同符号进行区分
markers={'Female':'v','Male':'P'} # 指定用什么符号
,hue='sex' #可以叠加颜色区分
,palette={'Female':'red','Male':'blue'} # 自定义颜色,当然案例简单,我就直接写颜色了
,size='sex'# 标记设置大小不同,纯演示,加这个有点多余了
,sizes=[25,40] # 设置标记大小
)
ax2.set_title('中高级阶段')
# 第三个图
sns.scatterplot(data=tips,x='total_bill',y='tip'
,ax=ax3,hue='sex',style='sex')
ax3.set_title('最高阶段,爱看不看,好看有啥用')
2.6 上述三个hue(颜色)、style(标记类型)、size(粗细大小),都有相应的hue_order,style_order,size_order
还是这个数据集,性别只有两类,我们换周几吃饭day,有四类
fig,ax=plt.subplots(2,2,figsize=(14,12))
sns.lineplot(data=tips,x='total_bill',y='tip'
,hue='day',ax=ax[0,0]
)
sns.lineplot(data=tips,x='total_bill',y='tip'
,hue='day',ax=ax[0,1]
,hue_order=['Thur','Sun','Sat','Fri']
)
ax[0,1].set_title('图例顺序和左图不一样')
sns.lineplot(data=tips,x='total_bill',y='tip'
,hue='day',ax=ax[1,0]
,size='time'
,hue_order=['Thur','Sun','Sat','Fri']
)
sns.lineplot(data=tips,x='total_bill',y='tip'
,hue='day',ax=ax[1,1]
,size='time'
,size_order=['Lunch','Dinner']
,hue_order=['Thur','Sun','Sat']
)
ax[1,1].set_title('少写一个就少一条线')
可以看到:
-
hue_order可以强行指定顺序,特别是在柱状图中,很有用;隐藏功能:限制所画的数据---比如本例中又4个星期几,但是图4中,我只写三个,就只会画三个。(该方法在relplot中,如指定了row、col,想只画一部分图,实测无法进行限制)
-
size_order也可以指定顺序,style_order同理,不演示了;
-
如果在一个fig下面画多个子图,指定不同的ax,不能用relplot,只能用lineplot()和scatterplot(),因为relplot是fig级的方法,不过可以用COL来表示,相当于直接自带一个多坐标轴画图方法。
-
同时,官网也说明了,hue,size,style都可以用来区分类别,但是三者都用的话,图太繁杂,花里胡哨不宜看懂,故一般用两个就行了,其中size粗细个人感觉不好用
2.7 hue_norm:tuple ormatplotlib.colors.Normalize
Either a pair of values that set the normalization range in data units or an object that will map from data units into a [0, 1] interval. Usage implies numeric mapping.
按照官网的翻译,是对数值型进行标准化,但是我在实际尝试中,发现基本上,是用来指定数据范围的,比如hue_norm=(min,max),会将min到max之间(取不到max)的数据进行上色,例如本数据中,吃饭人数SIZE=1-6,我们传size=(2,5)时,就会将2,3,4这三个数值,进行上色,范围外的就不管了。
fig,ax=plt.subplots(2,2,figsize=(14,12))
sns.lineplot(data=tips,x='total_bill',y='tip'
,hue='size'
,ax=ax[0,0]
)
sns.lineplot(data=tips,x='total_bill',y='tip'
,hue='size'
,hue_norm=(1,3)
,ax=ax[0,1]
)
ax[0,1].set_title('只有1,2是彩色,上传的图可能看不清',fontsize=16)
sns.lineplot(data=tips,x='total_bill',y='tip'
,hue='size'
,hue_norm=(2,4)
,ax=ax[1,0]
)
ax[1,0].set_title('未被限制的1和范围中的2,3是彩色,',fontsize=16)
sns.lineplot(data=tips,x='total_bill',y='tip'
,hue='size'
,hue_norm=(0,1)
,ax=ax[1,1]
)
ax[1,1].set_title('范围太大\太小=没设置,感觉这参数没太大用,',fontsize=12)
hue_norm这个参数感觉也没太大用,size_norm同理:
fig,ax=plt.subplots(1,2,figsize=(14,6))
sns.scatterplot(data=tips,x='day',y='total_bill'
,size='size',hue='size'
,ax=ax[0]
)
sns.scatterplot(data=tips,x='day',y='total_bill'
,size='size',hue='size'
,size_norm=(4,7)
,ax=ax[1]
)
ax[1].set_title('size_norm=(4,7)')
# 注意看图例,圆点大小的变化,比如设置了(4,7),则1,2,3是一样大,从4,5,6开始逐渐变大
# 当然4会跟前三个一样大,后面开始逐步变大
2.8 units ,根据分类,再多画一条线,用units参数时,要将estimator=None,即不进行聚合
units:vector or key indata
Grouping variable identifying sampling units. When used, a separate line will be drawn for each unit with appropriate semantics, but no legend entry will be added. Useful for showing distribution of experimental replicates when exact identities are not needed.[大意:将变量以不同的标识进行分组,使用时,将units里面的变量,单独绘制一条合适的线,但不会添加图例,在重复试验、对比分析中,若不需要明确标识每个线的图例,这个参数很有用]
2.9 sizes:list, dict, or tuple,设置线、点的大小,传个列表就是几个类别各用多大多粗的,传个元组就是下限上限,传个字典要一一对应。
An object that determines how sizes are chosen whensizeis used. List or dict arguments should provide a size for each unique data value, which forces a categorical interpretation. The argument may also be a min, max tuple.
plt.rcParams['font.sans-serif'] = ['SimHei'] # 中文字体设置-黑体
fig,ax=plt.subplots(2,2,figsize=(14,12))
sns.lineplot(data=tips,x='total_bill',y='tip'
,units='time'
,estimator=None,hue='sex'
,ax=ax[0,0]
)
ax[0,0].set_title('隐约看到不止2条线线')
sns.lineplot(data=tips,x='total_bill',y='tip'
,units='time',style='time'
,estimator=None,hue='sex'
,ax=ax[0,1]
)
ax[0,1].set_title('明显看出,总共有四条线')
sns.lineplot(data=tips,x='total_bill',y='tip'
,size='day',sizes=[1,2,3,4]
,ax=ax[1,0]
)
ax[1,0].set_title('设置size列表用不同粗细的线')
sns.lineplot(data=tips,x='total_bill',y='tip'
,size='day',sizes=(0.5,1.5)
,ax=ax[1,1]
)
2.10 palette 设置调色板,调色板这东西得自己慢慢研究,最好找个自带的,觉得比较好看的两三个,记下用就行
Method for choosing the colors to use when mapping thehuesemantic. String values are passed tocolor_palette(). List or dict values imply categorical mapping, while a colormap object implies numeric mapping.
fig,ax=plt.subplots(2,2,figsize=(14,12))
sns.scatterplot(data=tips,x='total_bill',y='tip',
hue='day',palette='pastel'
,ax=ax[0,0]
)
ax[0,0].set_title('推荐找一下默认的色系用')
sns.scatterplot(data=tips,x='total_bill',y='tip',
hue='day',palette=['firebrick','lightgreen','lightblue','orange'],ax=ax[0,1]
)
ax[0,1].set_title('可以自己传一系列颜色')
2.11 dashes 虚线类型,markers标记,boolean, list, or dictionary,都需要指定了style才能用。
dashes是在折线图中,用什么折线,可以自己指定,比如折线是2像素的线+1像素的点+4像素的线+2像素的点无线循环,即[2,1,4,2],或者[1,3]无线循环。
markers是用什么标记,当使用style时,两个默认都是TRUE的,即用系统给你选定的默认线型、标记,可以自己找一波,用列表、字典穿进去,除非搞什么报告优化图表,一般不太需要专门调。
fig,ax=plt.subplots(2,2,figsize=(14,12))
sns.scatterplot(data=tips,x='total_bill',y='tip',
hue='day',markers=True,style='day'
,ax=ax[0,0]
)
ax[0,0].set_title('用系统默认指定的点标记')
sns.scatterplot(data=tips,x='total_bill',y='tip',
hue='day',style='day',markers=['.','>','8','s']
,ax=ax[0,1]
)
ax[0,1].set_title('自定义点标记')
sns.lineplot(data=tips,x='total_bill',y='tip'
,style='sex',dashes=True,hue='sex'
,ax=ax[1,0]
)
ax[1,0].set_title('默认的不同虚线')
sns.lineplot(data=tips,x='total_bill',y='tip'
,style='sex'
,dashes=[[1,3],[4,2]]
,hue='sex'
,ax=ax[1,1]
)
ax[1,1].set_title('自定义不同虚线')
2.12 estimator :name of pandas method or callable or None
Method for aggregating across multiple observations of theyvariable at the samexlevel. IfNone, all observations will be drawn. 实际上,这个名字更应该叫aggregate,即分组聚合里面的聚合,同groupby--agg里面的agg:
fig,ax=plt.subplots(2,2,figsize=(14,12))
sns.lineplot(data=tips,x='day',y='total_bill'
,hue='sex',ax=ax[0,0]
)
sns.lineplot(data=tips,x='day',y='total_bill'
,hue='sex',ax=ax[0,1],estimator='mean'
)
sns.lineplot(data=tips,x='day',y='total_bill'
,hue='sex',ax=ax[1,0],estimator='min'
)
sns.lineplot(data=tips,x='day',y='total_bill'
,hue='sex',ax=ax[1,1],estimator='max'
)
在周四、五、六、日中,有不同的消费记录,默认绘图,会有颜色带,像fillbetween一样,默认用的均值。
2.13 errorbar :string, (string, number) tuple, or callable 调整置信区间的参数
曾用名:ci,现在用的话会告诉你deprecated不推荐使用了
这个我作为重点内容,以小白的角度,以几乎完全忘了数学、统计学的角度来解释,确保是个人都看的懂。
---后续修改,发现还是要知道基本的标准差、标准误、置信区间等统计学知识才行,不然无法讲解---
上图,我们发现了奇怪的阴影带,为了方便解释,我们换一个数据集。
下面我们换一个自带的flight数据,很简单,1949年-1960年,每年12个月,记录了1949年到1960年,每年各12个月飞机乘客的人数,总体上,乘客人数逐年增加。
我们发现画散点图并不是那么聪明,想换折线图,那么问题来了,如果以年为X轴,乘客人数为Y轴,画一条折线图,Y轴我到底用哪个月的数据呢,选谁都不好,只能选均值啦,选了均值,产生标准差、阴影带就解释的通了。
演示1:ci-deprecated,如果使用ci报警告
sns.lineplot(data=flight,x='year',y='passengers',ci=('sd'))
C:\Users\Administrator\AppData\Local\Temp\ipykernel_6812\1661636496.py:1: FutureWarning:
The `ci` parameter is deprecated. Use `errorbar=('ci', 2)` for the same effect.
演示2:errorbar四个可选参数:
Name of errorbar method (either “ci”, “pi”, “se”, or “sd”), or a tuple with a method name and a level parameter, or a function that maps from a vector to a (min, max) interval.
缩写让人懵逼,我们来看这四个到底代表什么意思:
pi: percentile interval 即百分比区间
sd: standard deviation 标准差,注意标准差要除以样本数n-1,
se: standard error 标准误差,除以样本数n,
ci: confidence interval 置信区间,很多alpha=0.05,用均值加减2倍的sigma,实际应该如下图。
要讲解errorbar,我们得先确定两个知识点:
(一)标准差和标准误差:
标准差:
标准误差
而python中自带的data.std方法,算的是标准差,会默认除以n-1,即ddof( Delta Degrees of Freedom)=1,方差就是标准差的平方,同理。
np.std(data)算的是标准误差,区别在自由度,numpy算的是标准误差,就是认为你的样本就是整体,除以n,总体方差同理。
毫无疑问,标准差因为除的n-1,数字肯定要大一点
# 我们把1960年的乘客数据单独拧出来算一算
temp_data = flight[flight['year']==1960]['passengers']
print('样本情况:\n',temp_data)
print('numpy算的标准误差:\n',np.std(temp_data))
print('自带方法算的标准差:\n',temp_data.std())
样本情况:
132 417
133 391
134 419
135 461
136 472
137 535
138 622
139 606
140 508
141 461
142 390
143 432
Name: passengers, dtype: int64
numpy算的标准误差:
74.42763077125473
自带方法算的标准差:
77.73712501797714
-------------------我们可以手算进行验证-----------------------------
print('standard error标准误差,除样本数')
print(np.sqrt(((data1960.passengers - data1960.passengers.mean())**2).sum()/12))
print('standard deviation标准差,除样本-1')
print(np.sqrt(((data1960.passengers - data1960.passengers.mean())**2).sum()/11))
standard error标准误差,除样本数
74.42763077125473
standard deviation标准差,除样本-1
77.73712501797714
(二)置信区间:
errorbar有四个,其中pi(百分比区间),sd(样本标准差,除n-1),se(标准误差,除以n)会用你提供的数据;
ci(置信区间),会用boostrap自助法,生成新的数据,重新计算标准误差。
我们从简单到难的将---
(1)pi,用法简单:
# 1.errorbar = pi
plt.subplot(2,1,1)
sns.lineplot(x=flight.year,y=flight.passengers,errorbar=('pi',60)) # 指定需要多少百分比区间
plt.subplot(2,1,2)
sns.lineplot(x=flight.year,y=flight.passengers,errorbar='pi') # 默认是95
# 意思是绘制平均值上下,最低取值2.5%的,最高取值97.5%的,即默认掐头去尾取中间95%的数值。
# 当然可以自己设置取多少的,例如80%
# 但是,不支持自定义,比如你想取10%到80%,两边不对称,不行,只能输入一个0到100之间的数值
Percentiles must be in the range [0, 100]
(2)sd,也比较简单,因为用的就是你传入的数据,只是计算标准差,除了n-1:
# 2.errorbar = sd
plt.subplot(2,1,1)
sns.lineplot(x=flight.year,y=flight.passengers,errorbar=('sd',2))
plt.subplot(2,1,2)
sns.lineplot(x=flight.year,y=flight.passengers,errorbar='sd')
# 如果不指定加减多少个标准差sigma,默认是1
# 接触过统计学的都知道,加减1个sigma会覆盖68%的数据,2个是95%,准确点是1.96个,3个是99.7%
(3) se,standard error 标准误差,与标准差的区别在于,除的是n,比如这份数据,每年12个月,n=12,算标准误差,就是除以12,也是默认只加减1个sigma,也可以自己指定加多少个,一般情况下,3个sigma基本涵盖了绝大部分数据,已经够大了。
(4)ci,Condifence interval,置信区间,这个是最不同最难的,此时需要介绍另一个知识,bootstrap自助法。
比如这个数据,一年12个月,每个月有一个数据,你认为没毛病,但是假如是让你统计一个城市高一男生的身高呢,你只统计了12个,然后搞出了一个均值,也可以,均值就按12个的平均,但是只有一个标准差,这你绘制身高波动阴影线,就完全没有说服力;
-----原谅我不想再搞这些公式了,就截个图----
# 四个不同的放一起,可以看看
fig,ax = plt.subplots(4,1,figsize=(8,10))
sns.lineplot(data=flight,x='year',y='passengers',ax=ax[0],errorbar='sd',err_style='band')
sns.lineplot(data=flight,x='year',y='passengers',ax=ax[1],errorbar=('se',1),err_style='bars')
sns.lineplot(data=flight,x='year',y='passengers',ax=ax[2],errorbar=('pi',100))
plt.axhline(y=flight[flight['year']==1960]['passengers'].mean(),color='red',alpha=0.5)
sns.lineplot(data=flight,x='year',y='passengers',ax=ax[3],errorbar=('ci',95),n_boot=3000)
根据排列组合公式,如果是12个不同的样本,有放回抽取12个,不同的情况会有个不同的情况,所以
几乎不会怎么重复!
我基本是按照自己的理解来讲,也查了一下各方资料,感觉讲清楚了,你也可以去官网Statistical estimation and error bars — seaborn 0.13.1 documentation看看。
2.14 n_boot :Number of bootstraps to use for computing the confidence interval
2.15 seed :Seed or random number generator for reproducible bootstrapping.
2.16 err_style,在“band” or “bars”里挑一个,效果如上图。
2.17 err_kws 调整置信区间其他参数,如颜色、透明度,百分之多少之类
2.18 orient,“x” or “y”,比如现在你有一份数据,年份和年销售总额,但是年份是乱序的,你可以指定x轴是年份,同时orient='x',即可!
Dimension along which the data are sorted / aggregated. Equivalently, the “independent variable” of the resulting function.
2.19 sort,boolean,If True, the data will be sorted by the x and y variables, otherwise lines will connect points in the order they appear in the dataset. 比较简单不说了。
2.20 legend,图例,“auto”, “brief”, “full”, or False
How to draw the legend.
-
If “brief”, numerichueandsizevariables will be represented with a sample of evenly spaced values.
-
If “full”, every group will get an entry in the legend.
-
If “auto”, choose between brief or full representation based on number of levels.
-
IfFalse, no legend data is added and no legend is drawn.
2.21 ax,只有使用lineplot,scatterplot时才有,上述代码中,一个画布多个坐标轴绘图,多次有用到。
2.22 kwargs,其他的绘图参数,因为seaborn是matplotlib的继承并优化的库,所以很多plt的参数,一样可以搞进去,像什么ls线条粗细,alpha透明度诸如此类。
三、relplot,相比之前说的lineplot,只多几个参数。
3.1 row,col,多行多列,分组显示
sns.relplot(data=tips,x='total_bill',y='tip',col='time',row='sex',hue='sex',style='time')
3.2 row_order, col_order,指定行列顺序,lists of strings
3.3 height,每个小图的高度,aspect 宽高比,宽度即height乘以aspect
当指定了row,col时,设定此参数
3.4 col_wrap :int限制每一行能显示多少个列,如果你同时指定了row=a,col=b,则不能用,只有在你单独指定了col=6,结果发现画面放这么多图很小,此时col_wrap=3,限制每行只能显示3个图,就会变成2行了,除不尽也可以,剩余的图会放在下一行。
[ValueError: Cannot use `row` and `col_wrap` together. ]
3.5 facet_kws :实在是写不动了,类似FacetGrid之类的,请查看其他文章。