RQL's Blog 菜鸟成长记

箱形图原理及绘制方法

2018-03-12
renql
ncl

箱形图(Box-plot)又称为盒须图、盒式图或箱线图,提供有关数据位置和分散情况的关键信息, 主要包含六个数据节点,将一组数据从大到小排列,分别计算出他的上边缘,上四分位数Q3,中位数,下四分位数Q1,下边缘,还有一个异常值。

各数据节点的计算

首先要把数据从大到小排序,没错,是从大到小。

1. 中位数

中位数,即二分之一分位数。所以计算的方法就是将一组数据平均分成两份,取中间这个数。
如果原始序列长度n是奇数,那么中位数所在位置是(n+1)/2;
如果原始序列长度n是偶数,那么中位数所在位置是n/2,n/2+1,中位数的值等于这两个位置的数的算数平均数。

2. 上四分位数Q1

四分位数的求法,是将序列平均分成四份。具体的计算目前有(n+1)/4与(n-1)/4两种,一般使用(n+1)/4。
R语言中可通过summary(test)来获取test这个序列的中位数,上四分位数,下四分位数以及算数平均值。
若有一序列长度n=8,(1+n)/4=2.25,说明上四分位数在第2.25个位置数,实际上这个数是不存在的,但我们知道这个位置是在第2个数与第3个数之间的。
只能假想从第2个数到第3个数之间是均匀分布的,那么第2.25个数 = (第三个数-第二个数)25/100 + 第二个数 = 第二个数0.75+第三个数*0.25。

3. 下四分位数Q3

这个下四分位数所在位置计算方法同上,只不过是(1+n)/4*3=6.75,这个是个介于第六个位置与第七个位置之间的地方。

4. 内限

目前我们文章中看到的这两个T形的盒须就是内限。
上面的T形线段所延伸到的极远处,是Q3+1.5IQR(其中,IQR=Q3-Q1)与剔除异常值后的极大值两者取最小,
下面的T形线段所延伸到的极远处,是Q1-1.5IQR与剔除异常值后的极小值两者取最大。

5. 外限

外限与内限的计算方法相同,唯一的区别就在于:
上面的T形线段所延伸到的极远处,是Q3+3IQR(其中,IQR=Q3-Q1)与剔除异常值后的极大值两者取最小,
下面的T形线段所延伸到的极远处,是Q1-3IQR与剔除异常值后的极小值两者取最大。

ncl画箱形图函数

load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/shea_util.ncl" ;这个不会自动调用

  plotres              = True                         ; plot mods desired
  plotres@tmXBLabels   = (/"Control","-2Xna","2Xna"/) ; labels for each box
  plotres@tiMainString = "Tailored Box Plot"          ; 无法设定左标题、右标题、中间标题
  ;可以使用gsn_text_ndc(wks,"string",x,y,tres)添加文字string,其中x,y是坐标,tres是逻辑值
  
plot = boxplot(wks,x,y,boxopts,plotres,lineres)  ;后三个参数都是逻辑值,用以设置绘图参数
  ;x是一维数组,表示要X轴的哪几个位置画箱形
  ;y是二维数组,第一维大小同x,第二维包含了箱形图5个重要数据
  ;y(n,0)=bottom_value, y(n,1)=bottom_value_of_box, y(n,2)=mid-value_of_box,
  ;y(n,3)=top_value_of_box,y(n,4)=top_value.
  ;boxopts有两个参数,boxWidth,boxColors,均可赋以一个数字或一维数组
  ;plotres设置xy-plot的参数,在某些情况下可能会被覆盖
  ;lineres设置箱形上下的那两条线
  
 draw(wks)  ; boxplot does not call these
 frame(wks)

注意:该函数可以与gsn_panel函数合用

但是,如何计算一组序列的四分点数呢?ncl官网介绍的简易版本代码如下,该版本无法判断异常值

var  = wgt_areaave_Wrap(rain(time,lat,lon),1,1,0)  ;有一一维数组
qsort(var) ;将一个一维数组从小到大排列,缺测值将安排序列的最后,dim_pqsort_n(x,kflag)可以将多维数组的任意一维升序或降序排列
dimt = dimsizes(var)
x25  = round(.25*dimt,3)-1     ; -1 to account for NCL indexing starting
x75  = round(.75*dimt,3)-1     ; at 0 
y    = (/min(var),var(x25),dim_median(var),var(x75),max(var)/)  ;下限,下四分位数,中位数,上四分位数,上限 

可以判断异常值版本代码如下

var  = wgt_areaave_Wrap(rain(time,lat,lon),1,1,0)  ;有一一维数组
qsort(var) ;将一个一维数组从小到大排列,缺测值将安排序列的最后,dim_pqsort_n(x,kflag)可以将多维数组的任意一维升序或降序排列
dimt = dimsizes(var)

x25  = floor(0.25*(dimt+1))
xx25 = 0.25*(dimt+1)-x25
x75  = floor(0.75*(dimt+1))
xx75 = 0.75*(dimt+1)-x75

y(1) = (var(x25)-var(x25-1))*xx25+var(x25-1)
y(2) = dim_median(var)
y(3) = (var(x75)-var(x75-1))*xx75+var(x75-1)
y(0) = y(3)-1.5*(y(3)-y(1))
y(4) = y(1)+1.5*(y(3)-y(1))

当值不在上限和下限之间即为异常值,添加额外的异常点的方法:  

  mres               = True                     ; marker mods desired
  mres@gsMarkerIndex = 3                        ; polymarker style
  mres@gsMarkerSizeF = 20.                      ; polymarker size
  mres@gsMarkerColor = "red"                    ; polymarker color
  xi  = yval(0,4)                               ; polymarker locations
  xi2 = yval(1,4)+0.25
  xi3 = yval(2,4)-0.25

  dum1 = gsn_add_polymarker(wks,plot,-3.,xi,mres) 
  dum2 = gsn_add_polymarker(wks,plot,-1.,xi2,mres) 
  dum3 = gsn_add_polymarker(wks,plot,1.,xi3,mres)

支持 支付宝鼓励 鸡腿鸡腿

喜欢此文!

Content