2017-06-29 67 views
0

在MATLAB中,boxplot命令可用於生成箱形圖。該函數的缺省行爲是具有1.5 * IQR(第75百分位 - 第25百分位數)的晶須長度,並且如果需要,該晶須長度可以改變爲IQR的另一個倍數。然而,使用特定百分位數作爲鬍鬚的限制是不可能的,這是我需要的(在我的情況下是第10和第90百分位)。正如你將在下面的例子中看到的,我已經到了這麼遠,但遇到了一個問題。從matlab boxplot中刪除某些異常值

考慮以下數據:

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函數生成的箱線圖:

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) 

然後我繼續使用圖形手柄編輯箱形圖(ed iting在我的情況盒子unnessary自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]) 

其結果如下:

enter image description here

正如你所看到的,隨着我對鬍鬚的改變,我的一些離羣值與鬍鬚重疊。

我的問題是如何確保在我的更改後,我的鬍鬚內的異常值被移除(並且在我的晶須外顯示)。我知道我需要以某種方式使用「異常值」處理,但解決方案並未向我展示...因爲這只是一個示例數據集,所以解決方案必須在大型數據集上工作。

+0

'H =箱線圖(Box_Data_PFCA,標籤)'就已經做你想做的。我不明白你爲什麼要自己設置盒子的邊界? – obchardon

+0

當然,如果你沒有異常值(這是你的情況與PFDA的情況下),什麼都不會被繪製。你沒有低於Q1 - 3 * IQ的價值或高於Q3 + 3 * IQ – obchardon

+0

@obchardon我自己設定邊界的原因是我想使用第10和第90百分位,而不是基於IQR的一些因素。 PDNA的第90百分位數是105.5,這個數據集中的數值爲110,我想表示爲離羣值(因爲它大於第90百分位數)。 – user1912925

回答

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) 

這導致在圖下方可以相比,我在這個問題原件。歡迎任何關於如何改進我的解決方案的提示!

enter image description here

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)

[/編輯]

+0

不幸的是,如果我使用這種方法,我會收到下面的錯誤(我懷疑我在這裏丟失了一些隱含的東西):「來自非結構數組對象的結構內容引用」。 – user1912925

+0

我更新了我的答案。 – Gelliant

+0

不幸的是,執行此行「idx = find(h(7,1).YData PFOS_10);」再次導致相同的錯誤:「來自非結構數組對象的結構內容引用」。大概這就是爲什麼需要「獲取」功能? – user1912925