如何将箱线图须绘制至Q1-1.5*IQR与Q3+1.5*IQR而非最值?
问题
我希望将数据点0.077414939与箱线图进行对比,绘图显示该点为异常值,但通过计算Q1-1.5IQR(下限为0.03658130324999995)和Q3+1.5IQR的上下界,发现该点不应被判定为异常值。请问如何将箱线图的须绘制到上述上下界,而非默认的最小值和最大值?

现有代码
import numpy as np import pandas as pd import seaborn as sns data = {'Center': [0.26857881, 0.25526688, 0.27575725, 0.25816567, 0.27839591, 0.25704223, 0.27876854, 0.25689208, 0.24568341, 0.27170329, 0.24951651, 0.26341556, 0.23330706, 0.26628367, 0.24271549, 0.26151005, 0.2194737, 0.22327154, 0.20390595, 0.23187327, 0.22729037, 0.24013772, 0.21812675, 0.24829089, 0.22292593, 0.21533798, 0.2375203, 0.24358, 0.23935491, 0.21955327, 0.25495809, 0.22418302, 0.23168249, 0.22031974, 0.19427523, 0.21487167, 0.22327235, 0.2334787, 0.21033593, 0.21257535, 0.19528684, 0.20617609, 0.21584015, 0.20789747, 0.20814228, 0.21319687, 0.22782205, 0.20793727, 0.22442598, 0.22854906, 0.2328641, 0.23012169, 0.22649554, 0.21118934, 0.1980712, 0.20799725, 0.19317045, 0.20426635, 0.18019197, 0.18720767, 0.18573065, 0.19297233, 0.19230893, 0.20739394, 0.20091433, 0.20808377, 0.21997453, 0.21432004, 0.2145078, 0.22670847, 0.2195935, 0.21880863, 0.22720217, 0.2405563, 0.24436345, 0.22278882, 0.23400447, 0.2128166, 0.2344685, 0.21768168, 0.23376607, 0.21818298, 0.234481, 0.22627898, 0.29847948, 0.23503119, 0.2308161, 0.19334404, 0.09538444, 0.11038104, 0.11524165, 0.09856957, 0.12746572, 0.1558064, 0.15951489, 0.12194555, 0.11833563, 0.1014696, 0.11559569, 0.11146258, 0.1315745, 0.09123692, 0.09131569, 0.10194323, 0.11820753, 0.11682336, 0.12112035, 0.15115081, 0.08319368, 0.10231317, 0.09921997, 0.12303618, 0.10655393, 0.11144342, 0.09901149, 0.09016768, 0.09824667, 0.12649639, 0.14759194, 0.14387346]} X = pd.DataFrame(data) def is_tukey(x, y, k=1.5): first_quartile = np.quantile(x, .25) third_quartile = np.quantile(x, .75) iqr = third_quartile - first_quartile lower_allowed_limit = first_quartile - (k * iqr) upper_allowed_limit = third_quartile + (k * iqr) in_range = (y > lower_allowed_limit) and (y < upper_allowed_limit) return in_range, lower_allowed_limit y = 0.077414939 is_tukey(X['Center'], y) sns.boxplot(X['Center']) sns.swarmplot([y], size=5, color='r')
解决方案
Seaborn默认的boxplot会把须延伸到数据中不超出Q1-1.5IQR/Q3+1.5IQR的最远点,而非直接延伸到计算出的理论上下界。要强制须绘制到你计算的Q1-1.5IQR和Q3+1.5IQR位置,不管数据中是否存在对应点,可通过以下两种方法实现:
方法1:手动计算上下界并修改箱线图元素
先计算四分位数、IQR及理论上下界,绘制箱线图后手动调整须的位置:
import numpy as np import pandas as pd import seaborn as sns import matplotlib.pyplot as plt data = {'Center': [0.26857881, 0.25526688, 0.27575725, 0.25816567, 0.27839591, 0.25704223, 0.27876854, 0.25689208, 0.24568341, 0.27170329, 0.24951651, 0.26341556, 0.23330706, 0.26628367, 0.24271549, 0.26151005, 0.2194737, 0.22327154, 0.20390595, 0.23187327, 0.22729037, 0.24013772, 0.21812675, 0.24829089, 0.22292593, 0.21533798, 0.2375203, 0.24358, 0.23935491, 0.21955327, 0.25495809, 0.22418302, 0.23168249, 0.22031974, 0.19427523, 0.21487167, 0.22327235, 0.2334787, 0.21033593, 0.21257535, 0.19528684, 0.20617609, 0.21584015, 0.20789747, 0.20814228, 0.21319687, 0.22782205, 0.20793727, 0.22442598, 0.22854906, 0.2328641, 0.23012169, 0.22649554, 0.21118934, 0.1980712, 0.20799725, 0.19317045, 0.20426635, 0.18019197, 0.18720767, 0.18573065, 0.19297233, 0.19230893, 0.20739394, 0.20091433, 0.20808377, 0.21997453, 0.21432004, 0.2145078, 0.22670847, 0.2195935, 0.21880863, 0.22720217, 0.2405563, 0.24436345, 0.22278882, 0.23400447, 0.2128166, 0.2344685, 0.21768168, 0.23376607, 0.21818298, 0.234481, 0.22627898, 0.29847948, 0.23503119, 0.2308161, 0.19334404, 0.09538444, 0.11038104, 0.11524165, 0.09856957, 0.12746572, 0.1558064, 0.15951489, 0.12194555, 0.11833563, 0.1014696, 0.11559569, 0.11146258, 0.1315745, 0.09123692, 0.09131569, 0.10194323, 0.11820753, 0.11682336, 0.12112035, 0.15115081, 0.08319368, 0.10231317, 0.09921997, 0.12303618, 0.10655393, 0.11144342, 0.09901149, 0.09016768, 0.09824667, 0.12649639, 0.14759194, 0.14387346]} X = pd.DataFrame(data) y = 0.077414939 # 计算四分位数和理论上下界 q1 = np.quantile(X['Center'], 0.25) q3 = np.quantile(X['Center'], 0.75) iqr = q3 - q1 lower_bound = q1 - 1.5 * iqr upper_bound = q3 + 1.5 * iqr # 绘制箱线图 plt.figure(figsize=(8,6)) box = sns.boxplot(x=X['Center'], whis=1.5) # 获取箱线图的须和端点元素 whiskers = box.lines[2:4] # 下须、上须 caps = box.lines[4:6] # 下须端点、上须端点 # 修改下须及端点位置 whiskers[0].set_ydata([lower_bound, q1]) caps[0].set_ydata([lower_bound, lower_bound]) # 修改上须及端点位置 whiskers[1].set_ydata([q3, upper_bound]) caps[1].set_ydata([upper_bound, upper_bound]) # 绘制对比点 sns.swarmplot(x=[y], size=7, color='r') plt.show()
方法2:使用Matplotlib原生boxplot指定须范围
Matplotlib的boxplot支持直接通过whis参数指定须的范围,将计算好的理论上下界传入即可:
import numpy as np import pandas as pd import matplotlib.pyplot as plt data = {'Center': [0.26857881, 0.25526688, 0.27575725, 0.25816567, 0.27839591, 0.25704223, 0.27876854, 0.25689208, 0.24568341, 0.27170329, 0.24951651, 0.26341556, 0.23330706, 0.26628367, 0.24271549, 0.26151005, 0.2194737, 0.22327154, 0.20390595, 0.23187327, 0.22729037, 0.24013772, 0.21812675, 0.2
相关产品推荐
相关产品推荐

