当前位置: 首页 > 科技观察

Python数据可视化:箱线图多种库绘制方法

时间:2023-03-14 13:39:01 科技观察

概念箱线图通过数据的四分位数来展示数据的分布情况。例如:数据的中心位置,数据之间的离散程度,是否存在异常值等。将数据从小到大排列,分成四等份。第一分位数(Q1)、第二分位数(Q2)和第三分位数(Q3)分别是数据的第25、50和50个百分位数。75%的数字。四分位距(IQR)=上四分位数(upperquartile)-下四分位数(lowerquartile)箱形图分为两部分,即方框(box)和晶须(whisker)。方框用来表示从第一个分位数到第三个分位数的数据,胡须用来表示数据的范围。箱形图从上到下的横线分别代表:数据上限(通常为Q3+1.5IQR)、第三分位数(Q3)、第二分位数(中位数)、第一分位数(Q1)、数据下限(通常为Q1-1.5IQR)。有时会有一些点,位于数据的上下限之外,表示异常值。(注意:如果数据的上下限特别大,那么whisker会显示数据的最大值和最小值。)案例一、使用pandas自带的函数,使用pandas中的dataframe数据结构存储要显示的数据。如果你要显示的每个数据列表中的数据长度不一致,可以先用Series函数转换成Series数据,然后存入dataframe中。如果索引对应的值不存在,则为NaN。下面我们随机生成4组数据,看看它们的箱线图。[代码]importnumpyasnpimportpandasasddrommatplotlibimportpyplotaspltdeflist_generator(mean,dis,number):#封装此函数,稍后生成数据returnnp.random.normal(mean,dis*dis,number)#正态分布,输入参数为均值、标准差和生成量#我们生成了四组数据进行实验,数据量为70-100y1=list_generator(0.8531,0.0956,70)y2=list_generator(0.8631,0.0656,80)y3=list_generator(0.8731,0.1056,90)y4=list_generator(0.8831),0.0756,100)#如果数据大小不同,记得需要下面的语句把数组改成seriesy1=pd.Series(np.array(y1))y2=pd.Series(np.array(y2)))y3=pd.Series(np.array(y3))y4=pd.Series(np.array(y4))data=pd.DataFrame({"1":y1,"2":y2,"3":y3,"4":y4,})data.boxplot()#这里pandas有自己的处理过程,非常方便。plt.ylabel("ylabel")plt.xlabel("xlabel")#我们设置标题的横纵坐标。plt.show()[效果]上面的箱线图非常简单。数据给定后,几行代码就可以生成,不过这是一个简单的箱线图。让我们看一些更复杂的东西。2.使用matplotlib库绘制箱线图上面我们已经介绍了使用pandas绘制箱线图,几个命令就可以了。但对于稍微复杂一点的,您可以使用matplotlib库。matplotlib代码有点复杂,但很灵活。细心的你会发现pandas中的绘图也是基于这个库的。给大家看下pandas中的源码:通过源码可以看出pandas中的绘图也是调用matplotlib来完成的。那我们自己用matplotlib画一个boxplot吧。下面简单模拟一下20岁和30岁的男女生成本对比图,用箱线图可视化。[代码]importnumpyasnpimportmatplotlib.pyplotaspltfig,ax=plt.subplots()#subplotdeflist_generator(mean,dis,number):#封装这个函数以后生成数据returnnp.random.normal(mean,dis*dis,number)#正态分布,输入参数为均值、标准差和生成量#我们生成四组数据进行实验,数据量分别为70-100#代表20岁和30岁男孩和女孩的开销分布girl20=list_generator(1000,29.2,70)boy20=list_generator(800,11.5,80)girl30=list_generator(3000,25.1056,90)boy30=list_generator(1000,19.0756,100)data=[girl20,boy20,girl30,boy,]ax.boxplot(data)ax.set_xticklabels(["girl20","boy20","girl30","boy30",])#设置x轴刻度标签plt.show()【效果】从上面随机模拟,它可见男生的消费跟不上女生,尤其是30岁以后,女生比男生便宜很多。(模拟数据,请勿当真)仔细看上图,感觉还是不太好。既然是对比男女生,是不是要分组,把男女生放在一起,然后按年龄段来比较,这样比较起来更直观。然后我们将上面的代码稍微修改一下,让男孩和女孩的箱线图靠得更近一些。函数定义:boxplot(x=None,y=None,hue=None,data=None,order=None,hue_order=None,orient=None,color=None,palette=None,saturation=.75,width=.8,dodge=True,fliersize=5,linewidth=None,whis=1.5,notch=False,ax=None,**kwargs)【参数说明】x,y:dataframe或vectordata中的列名(str)data:dataframe或数组palette:palette,控制图像的色调hue(str):dataframe的列名,根据列名中的值进行分类,形成分类柱状图顺序,hue_order(listsofstrings):用于控制bargraphorient的顺序:"v"|"h"用于控制图片是水平显示还是垂直显示(这个通常是根据输入变量的dtype推断的,一般不传这个参数inx,y,onlydata时使用)fliersize:float,用于表示异常值观测值的标记大小whis:确定异常值的上下界(IQR超过low和high的比值四分位数),超出此范围的点将被识别为异常值。IQR指的是上四分位数和下四分位数之间的差异。width:float,控制箱线图的宽度。我们还是基于上面男女成本的例子,但是这里我们把数据整理一下,做成一个数据框。【包含的库】importpandasaspdimportnumpyasnpimportseabornassnsimportmatplotlib.pyplotasplt#plt.rc("font",family="SimHei",size="15")避免中文乱码,不需要【第一部分代码】数据生成deflist_generator(mean,dis,number):#封装这个函数,以后生成数据returnnp.random.normal(mean,dis*dis,number)#正态分布,输入参数为均值、标准差和生成数量#我们生成四个做实验的数据组,数据量为70-100#分别代表20岁和30岁男生和女生的分布#构建数据库DataFramenum=100#每组100个样本girl20=list_generator(1000,29.2,num)boy20=list_generator(800,11.5,num)girl30=list_generator(3000,25.1056,num)boy30=list_generator(1000,19.0756,num)girl_sex=['female'for_inrange(num)]boy_sex=['male'for_inrange(num)]age20=[20for_inrange(num)]age30=[30for_inrange(num)]girl_d1=pd.DataFrame({'cost':girl20,'sex':girl_sex,'age':age20})boy_d1=pd.DataFrame({'cost':girl20,'sex':girl_sex,'age':age20})boy_d1=pd.DataFrame({'cost':boy20,'sex':boy_sex,'age':age20})girl_d2=pd.DataFrame({'cost':girl30,'sex':girl_sex,'age':age30})boy_d2=pd.DataFrame({'cost':boy30,'sex':boy_sex,'age':age30})data=pd.concat([girl_d1,boy_d1,girl_d2,boy_d2])print(data.head())数据是什么样子的?下面是给定数据框的前面部分,一共400个样本,分为性别和年龄【代码二】使用seaborn库画图简单看下所有数据的分布:sns.boxplot(x=data["cost"],data=data)按性别分组:sns.boxplot(x="age",y="cost",data=data,hue="sex",width=0.5,linewidth=1.0,palette="Set3")按年龄分组:sns.boxplot(x="sex",y="cost",data=data,hue="age",width=0.5,linewidth=1.0,palette="Set3")以上是seaborn库的简单使用。可以按年龄比较男女的开支,也可以按性别比较不同年龄段的开支。这是非常直观的。当然除此之外还有很多其他的炫技,大家可以自己去试试。小结从以上来看,虽然我们绘制箱线图的方法不同,但最基本的还是调用matplotlib库。Pandas是最简单的箱线图可视化,但不灵活。matplotlib虽然灵活,但需要慢慢调整,复杂。相比之下,seaborn更酷,画面也更好看。以上实例均为亲测,一一对比,原创文章,如有其他问题,可留言讨论。