2010-08-05 17 views
15

vorrei riprodurre la figura seguente in MATLAB:ellisse attorno ai dati in MATLAB

exampleee.png

Ci sono due classi di punti con coordinate X e Y. Mi piacerebbe circondare ogni classe con un'ellisse con un parametro di deviazione standard, che determina la distanza dell'ellisse lungo l'asse.

La figura è stata creata con un altro software e non capisco esattamente come calcola l'ellisse.

Ecco i dati che sto utilizzando per questa figura. La prima colonna è class, 2nd - X, 3rd - Y. Posso usare gscatter per disegnare i punti.

A = [ 
    0 0.89287 1.54987 
    0 0.69933 1.81970 
    0 0.84022 1.28598 
    0 0.79523 1.16012 
    0 0.61266 1.12835 
    0 0.39950 0.37942 
    0 0.54807 1.66173 
    0 0.50882 1.43175 
    0 0.68840 1.58589 
    0 0.59572 1.29311 
    1 1.00787 1.09905 
    1 1.23724 0.98834 
    1 1.02175 0.67245 
    1 0.88458 0.36003 
    1 0.66582 1.22097 
    1 1.24408 0.59735 
    1 1.03421 0.88595 
    1 1.66279 0.84183 
]; 

gscatter(A(:,2),A(:,3),A(:,1)) 

Cordiali saluti, here è la domanda SO su come disegnare un'ellisse. Quindi, abbiamo solo bisogno di conoscere tutti i parametri per disegnarlo.


Aggiornamento:

Sono d'accordo che il centro può essere calcolato come mezzo di coordinate X e Y. Probabilmente dovrò usare l'analisi delle componenti principali (PRINCOMP) per ogni classe per determinare l'angolo e la forma. Ancora pensando ...

+0

Anche se non si sa come l'ellisse nella figura originale è calcolato, si potrebbe forse spiegare un po 'di più quello che si suppone a dire? Non si tratta solo di circondare i punti come per i punti grigi, ad esempio, non tutti i punti sono inclusi nell'ellisse. Se non sapete nulla, suggerirei il baricentro dei punti come il centro dell'ellisse come punto di partenza. Il secondo momento dell'area potrebbe darti la direzione dell'asse maggiore. – groovingandi

+0

@groovingandi: Fondamentalmente significa che se l'ellisse viene disegnata con la deviazione standard 3, con distribuzione normale includerà circa il 99% dei punti dati. Le ellissi sulla figura sono state generate con STD = 2. – yuk

risposta

17

Si consideri il codice:

%# generate data 
num = 50; 
X = [ mvnrnd([0.5 1.5], [0.025 0.03 ; 0.03 0.16], num) ; ... 
     mvnrnd([1 1], [0.09 -0.01 ; -0.01 0.08], num) ]; 
G = [1*ones(num,1) ; 2*ones(num,1)]; 

gscatter(X(:,1), X(:,2), G) 
axis equal, hold on 

for k=1:2 
    %# indices of points in this group 
    idx = (G == k); 

    %# substract mean 
    Mu = mean(X(idx,:)); 
    X0 = bsxfun(@minus, X(idx,:), Mu); 

    %# eigen decomposition [sorted by eigen values] 
    [V D] = eig(X0'*X0 ./ (sum(idx)-1));  %#' cov(X0) 
    [D order] = sort(diag(D), 'descend'); 
    D = diag(D); 
    V = V(:, order); 

    t = linspace(0,2*pi,100); 
    e = [cos(t) ; sin(t)];  %# unit circle 
    VV = V*sqrt(D);    %# scale eigenvectors 
    e = bsxfun(@plus, VV*e, Mu'); %#' project circle back to orig space 

    %# plot cov and major/minor axes 
    plot(e(1,:), e(2,:), 'Color','k'); 
    %#quiver(Mu(1),Mu(2), VV(1,1),VV(2,1), 'Color','k') 
    %#quiver(Mu(1),Mu(2), VV(1,2),VV(2,2), 'Color','k') 
end 

screenshot


EDIT

Se si desidera l'ellisse di rappresentare uno specifico livello di deviazione standard, la corretta il modo di procedere è ridimensionare la matrice di covarianza:

STD = 2;      %# 2 standard deviations 
conf = 2*normcdf(STD)-1;  %# covers around 95% of population 
scale = chi2inv(conf,2);  %# inverse chi-squared with dof=#dimensions 

Cov = cov(X0) * scale; 
[V D] = eig(Cov); 

OP_DATA

+0

Inoltre, si potrebbe voler controllare lo script demo 'eigshow' in MATLAB: http://www.mathworks.com/company/newsletters/news_notes/clevescorner/win98cleve.html – Amro

+0

Questo è fantastico. Grazie mille. Non sapevo molto come utilizzare gli autovettori/autovalori, ma ora posso vedere chiaramente come funziona questa roba. La cosa minore Se eseguo il tuo codice ottengo ellissi più piccoli. Se faccio 'STD = 2; VV = V * sqrt (D) * STD; ', le ellissi hanno le stesse dimensioni del tuo e del mio grafico originale. È corretto? Questo moltiplicatore corrisponde veramente a quello che l'altro software (io usavo per disegnare la figura originale) chiama la deviazione standard? – yuk

+1

@ yuk: hai ragione riguardo alla figura sopra, ma il modo corretto per farlo è ridimensionare la matrice di covarianza. Si prega di vedere la mia modifica sopra – Amro

2

mi piacerebbe provare il seguente approccio:

  1. Calcolare il baricentro xy per il centro dell'ellisse (x, y nel linked question)
  2. Calcolare la linea in forma di regressione lineare per ottenere l'orientamento dell'asse maggiore dell'ellisse (angolo)
  3. Calcolare la deviazione standard nella assi x e Y
  4. tradurre le deviazioni standard xy quindi sono ortogonale alla linea di misura (a, b)
+0

Cura di spiegare il downvote? C'è qualcosa di concettuale sbagliato nel mio approccio? – Doresoom

+0

Non ero io. Sto ancora pensando a come implementarlo. – yuk

+0

Questo approccio darebbe un risultato simile (ma non identico). Vi sono grandi differenze tra una regressione lineare, in cui viene considerata la deviazione solo nell'asse y e l'autovettore. È possibile che il calcolo della regressione lineare, la rotazione dei dati e la ripetizione di questo processo porterebbero a un risultato identico. Ciò minimizzerebbe la somma dei quadrati lungo un asse perpendicolare alla linea di regressione invece che solo nell'asse y. –

1

Suppongo che vi sia un solo insieme di punti indicato in una singola matrice, ad es.

B = A(1:10,2:3); 

è possibile riprodurre questa procedura per ciascun set di dati.

  1. Calcolare il centro dell'ellissoide, che è la media dei punti. Funzione Matlab: mean
  2. Centra i tuoi dati. Funzione Matlab bsxfun
  3. Calcola l'asse principale dell'ellissoide e la rispettiva grandezza. Funzione Matlab: eig

sono illustrate di seguito Le fasi successive:

Center = mean(B,1); 
Centered_data = bsxfun(@minus,B,Center); 
[AX,MAG] = eig(Centered_data' * Centered_data); 

Le colonne AX contiene i vettori che descrivono l'asse principale dell'ellissoide mentre la diagonale di MAG contiene informazioni sulla loro grandezza. Per tracciare l'ellissoide, ridimensionare ciascun asse principale con la radice quadrata della sua grandezza.

Spero che questo aiuti.

A.