在MATLAB中,boxplot命令可用于生成箱图。此函数的默认行为是晶须长度为1.5 * IQR(第75百分位数 - 第25百分位数),如果需要,此晶须长度可以更改为IQR的另一倍数。但是,不可能使用特定的百分位数作为胡须的限制,这是我需要的(在我的例子中是第10和第90百分位数)。正如您将在下面的示例中看到的那样,我到目前为止已遇到问题。
考虑以下数据:
Box_Data_PFCA = [-3;1;2;3;4;5;5;5;6;40;45;77;7;9;1;2;3;7;7;7;10;11;11;40;30;101;110;150];
label = ['PFOS';'PFOS';'PFOS';'PFOS';'PFOS';'PFOS';'PFOS';'PFOS';'PFOS';'PFOS';'PFOS';'PFOS';'PFOS';'PFOS';...
'PFDA';'PFDA';'PFDA';'PFDA';'PFDA';'PFDA';'PFDA';'PFDA';'PFDA';'PFDA';'PFDA';'PFDA';'PFDA';'PFDA'];
我使用defualt matlab函数生成一个boxplot:
h = boxplot(Box_Data_PFCA,label)
然后我计算生成箱线图所需的百分位数:
PFOS_10=prctile([-3;1;2;3;4;5;5;5;6;40;45;77;7;9],10)
PFOS_25=prctile([-3;1;2;3;4;5;5;5;6;40;45;77;7;9],25)
PFOS_75=prctile([-3;1;2;3;4;5;5;5;6;40;45;77;7;9],75)
PFOS_90=prctile([-3;1;2;3;4;5;5;5;6;40;45;77;7;9],90)
PFDA_10=prctile([1;2;3;7;7;7;10;11;11;40;30;101;110;150],10)
PFDA_25=prctile([1;2;3;7;7;7;10;11;11;40;30;101;110;150],25)
PFDA_75=prctile([1;2;3;7;7;7;10;11;11;40;30;101;110;150],75)
PFDA_90=prctile([1;2;3;7;7;7;10;11;11;40;30;101;110;150],90)
然后我继续使用图形句柄编辑方框图(在我的情况下编辑框是不确定的,因为25%到75%的默认设置适合我,但我显示完整性):
set(h(5,1), 'YData', [PFOS_25 PFOS_75 PFOS_75 PFOS_25 PFOS_25])
set(h(1,1), 'YData', [PFOS_75 PFOS_90])
set(h(2,1), 'YData', [PFOS_10 PFOS_25])
set(h(3,1), 'YData', [PFOS_90 PFOS_90])
set(h(4,1), 'YData', [PFOS_10 PFOS_10])
set(h(5,2), 'YData', [PFDA_25 PFDA_75 PFDA_75 PFDA_25 PFDA_25])
set(h(1,2), 'YData', [PFDA_75 PFDA_90])
set(h(2,2), 'YData', [PFDA_10 PFDA_25])
set(h(3,2), 'YData', [PFDA_90 PFDA_90])
set(h(4,2), 'YData', [PFDA_10 PFDA_10])
导致以下结果:
正如你所看到的,我对胡须的改变后,我的一些异常值与胡须重叠。
我的问题是如何确保在我的更改后,我的胡须内的异常值被移除(并且在我的胡须之外)。我意识到我需要以某种方式使用'Outliers'句柄,但解决方案并没有呈现给我...因为这只是一个示例数据集,解决方案必须处理大型数据集。
答案 0 :(得分:1)
因此,如果一个点小于最高胡须,并且大于最低胡须,则会删除它们。
您只能通过h
变量检查自己的位置。
像这样的东西:
idx = find(h(6:end,1).YData<PFOS_90&h(6:end,1).YData>PFOS_10);
h(5+idx,1)=[];
[编辑]
很高兴上面的想法指出了一个有效的解决方案!你的代码有点长,但非常易读。这也很重要。但也许这四条线做同样的工作?
idx = find(h(7,1).YData<PFOS_90&h(7,1).YData>PFOS_10);
h(7,1).YData(idx)=[];h(7,1).XData(idx)=[];
idx = find(h(7,2).YData<PFOS_90&h(7,2).YData>PFOS_10);
h(7,2).YData(idx)=[];h(7,2).XData(idx)=[];
如果你有很多要删除的点,你需要检查的不仅仅是(7,1)和(7,2)吗?在这种情况下,请使用for i = 1:size(h,2)
[/编辑]
答案 1 :(得分:0)
关注@Gelliants提示我已经设法找到了解决方案。它不漂亮,毫无疑问会更精致,但它的工作原理。我将以下代码行添加到我的问题中发布的代码:
a = get(h(7,1), 'YData')
b = get(h(7,1), 'XData')
idx = find(a<PFOS_90&a>PFOS_10)
a(idx)=[]
b(idx)=[]
set(h(7,1), 'YData', a, 'XData', b)
e = get(h(7,2), 'YData')
f = get(h(7,2), 'XData')
idx = find(e<PFDA_90&e>PFDA_10)
e(idx)=[]
f(idx)=[]
set(h(7,2), 'YData', e, 'XData', f)
这导致下面的图表可以与问题中的原始图表进行比较。欢迎提供有关如何优化我的解决方案的任何提示!