2017-06-29 5 views
0

Innerhalb von MATLAB kann der Boxplot-Befehl zum Generieren von Boxplots verwendet werden. Das Standardverhalten dieser Funktion hat eine Whiskerlänge von 1,5 * IQR (75. Perzentil - 25. Perzentil) und diese Whiskerlänge kann bei Bedarf auf ein anderes Vielfaches von IQR geändert werden. Es ist jedoch nicht möglich, spezifische Perzentile als Grenze der Whiskers zu verwenden, und das ist etwas, was ich benötige (in meinem Fall das 10. und das 90. Perzentil). Wie Sie im folgenden Beispiel sehen werden, bin ich soweit gekommen, habe aber ein Problem festgestellt.Entfernen bestimmter Ausreißer aus Matlab Boxplot

Betrachten Sie die folgenden Daten:

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']; 

Von dem mir einen boxplot mit der defualt Matlab-Funktion erzeugen:

h = boxplot(Box_Data_PFCA,label) 

ich dann die Perzentil berechnen Ich benötige eine boxplot zu generieren:

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) 

Ich fahre dann fort, das Boxplot mit den grafischen Handles zu bearbeiten (ed die Box in meinem Fall iting ist, da die Standardeinstellungen von 25% bis 75% Anzug mich unnessary aber ich zeige es auf Vollständigkeit):

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]) 

, die in den folgenden Ergebnissen:

enter image description here

Wie Sie sehen können, überschneiden sich einige meiner Ausreißer mit den Schnurrhaaren nach den Änderungen, die ich an den Schnurrhaaren vorgenommen habe.

Meine Frage ist, wie kann ich sicherstellen, dass Ausreißer in meinen Schnurrhaaren entfernt werden (und außerhalb meiner Schnurrhaare angezeigt werden) nach meinen Änderungen. Mir ist klar, dass ich den "Ausreißer" -Handgriff irgendwie verwenden muss, aber die Lösung stellt sich mir nicht vor ... Da dies nur ein Beispieldatensatz ist, müsste die Lösung an großen Datensätzen arbeiten.

+0

'h = boxplot (Box_Data_PFCA, Label)' bereits tun, was Sie wollen. Ich verstehe nicht, warum du die Boxgrenze selbst einstellst? – obchardon

+0

Natürlich, wenn Sie keine Ausreißer haben (dies ist Ihr Fall mit dem Fall PFDA), wird nichts geplottet. Sie haben keinen niedrigeren Wert als Q1 - 3 * IQ oder höher als Q3 + 3 * IQ – obchardon

+0

@obchardon der Grund, warum ich die Grenzen selbst gesetzt habe ist, dass ich die 10. und 90. Perzentile und nicht einige Faktoren basierend auf dem IQR verwenden möchte. Auch das 90. Perzentil von PDNA ist 105.5 und es gibt einen Wert von 110 in diesem Datensatz, den ich als Ausreißer anzeigen möchte (da er größer ist als das 90. Perzentil). – user1912925

Antwort

0

Nach @Gelliants Tipp habe ich es geschafft haben, eine Lösung zu verstehen. Es ist nicht schön und kann zweifellos raffinierter sein, aber es funktioniert. Ich fügen Sie die folgenden Zeilen Code zu denen in meiner Frage gestellt:

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) 

Dies führt zu dem Grundstück, unter dem zu meiner ursprünglichen in der Frage verglichen werden können.Irgendwelche Tipps, wie ich meine Lösung verbessern kann, sind willkommen!

enter image description here

1

Wenn also ein Punkt kleiner als Ihr höchster Whisker und größer als der niedrigste ist, würden Sie sie entfernen.

Können Sie nicht einfach ihre Position von Ihrer h Variable überprüfen. etwas wie folgt aus:

idx = find(h(6:end,1).YData<PFOS_90&h(6:end,1).YData>PFOS_10); 
h(5+idx,1)=[]; 

[Bearbeiten]

Glad die Idee oben aufgezeigt Sie auf eine funktionierende Lösung! Ihr Code ist ein bisschen lang, aber sehr gut lesbar. Das ist auch wichtig. Aber vielleicht machen diese vier Linien die gleiche Arbeit?

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)=[]; 

Kann es sein, dass, wenn Sie viele Punkte haben entfernen Sie mehr als nur überprüfen müssen (7,1) und (7,2)? In diesem Fall legen Sie eine Schleife mit for i = 1:size(h,2)

[/ edit]

+0

Leider, wenn ich diesen Ansatz verwende, erhalte ich den folgenden Fehler (ich vermute, dass ich hier implizite etwas vermisse): "Struct Inhalt Verweis von einem Nicht-Struktur-Array-Objekt." – user1912925

+0

Ich habe meine Antwort aktualisiert. – Gelliant

+0

Leider ist die Implementierung dieser Zeile "idx = find (h (7,1) .YData PFOS_10);" führt noch einmal zu dem gleichen Fehler: "Struct-Inhaltsverweis von einem Nicht-Struct-Array-Objekt". Vermutlich ist deshalb die "get" -Funktion gefragt? – user1912925

Verwandte Themen