画boxplot的接口为 matplotlib.pyplot.boxplot,不过在画之前,我需要好好理解一下箱体图所代表的含义和计算方法。
用一个实际的例子来说明如何画boxplot,这个例子来自wiki。
有数据 dd = [50,50,55,58,63,66,66,67,67,68,69,70,70,70,70,72,73,75,75,76,76,78,79,81],len(dd)=24,这一组数据表示的是一天当中每隔一小时的温度采样,按从小到大排列。
在画boxplot时,我们需要知道5个summary数字,five-number summary:
最小的数,min,是50;
最大的数,max,是81;
中间的数,median,70,计算方法:选出的这个数,意味着有50%的数大于它,有50%的数小于它;本例dd中数据个数是偶数,计算方法为把中间的两个数相加后除以2;
Q1,first quartile value,从小到大的第1个四分位数,66,计算方法:有25%的数小于Q1,有75%数大于Q1,同样,边界处不必太纠结;
Q3,thrid quartile value,从小到大第3个四分位数,75,计算方法:有25%的数大于Q3,有75%的数小于Q3;
注意:这5个数都是dd中实际存在的数!median和Q1,Q3确定了boxplot的中间3条线,即确定了中间的那个box。
计算IQR,InterQuartile Range,IQR = Q3 - Q1 = 75 - 66 = 9;
计算 1.5 * IQR = 13.5;
计算 Q1 - 1.5*IQR = 52.5;
计算 Q3 + 1.5*IQR = 88.5;
最低的那条线(lower whisker)是大于Q1-1.5*IQR的数中最小的那个,55;
最高的那条线(upper whisker)是小于Q3-1.5*IQR的数中最大的那个,81;
不在 lower whisker和 upper whisker之间的数,被称为 outliers,比例中的 outlier是50;
到此,所有需要画在boxplot中的点位都确定了,下面开始用matplotlib画:
import matplotlib.pyplot as plt
dd = [50,50,55,58,63,66,66,67,67,68,69,70,70,70,70,72,73,75,75,76,76,78,79,81]
plt.boxplot(dd)
plt.plot((0,2),(70,70), linewidth=0.5)
plt.plot((0,2),(66,66), linewidth=0.5)
plt.plot((0,2),(75,75), linewidth=0.5)
plt.plot((0,2),(81,81), linewidth=0.5)
plt.plot((0,2),(55,55), linewidth=0.5)
plt.plot((0,2),(50,50), linewidth=0.5)
plt.show()
我刻意多画了几条线出来,来检查我们手动计算的结果是否正确。效果如下:
用matplotlib画箱体图(boxplot)
同样,plt.boxplot接口也有很多参数来控制具体boxplot的样式,请参考官方说明:https://matplotlib.org/api/_as_gen/matplotlib.pyplot.boxplot.html#matplotlib.pyplot.boxplot
boxplot和正太分布
boxplot实际上体现了dataset中数据的分布情况,多个boxplot放在一起比较很方便。看图吧:
boxplot和正态分布分布
boxplot中的outliers就是属于少于1%的异类!
median不是mean
统计学中的median是指中间位置,而mean才是平均。boxplot计算median这个数,当数据个数为偶数时,median等于中间位置的两个数相加除以2。
import matplotlib.pyplot as plt
dd = [1,1,1,1,9,9,9,9]
plt.boxplot(dd)
plt.show()
这几行代码画出来的boxplot,中间那条线的位置为 y=(1+9)/2=5,请同学们自己测试。
-- EOF --