Ho un vettore che contiene alcuni punti nello spazio 2D. Voglio MATLAB per tracciare questi punti con linee tracciate da ogni punto a ogni altro punto. Fondamentalmente, voglio un grafico con tutti i vertici connessi. Puoi farlo con la trama e se sì, come?Come faccio a tracciare linee tra tutti i punti di un vettore?
risposta
Una soluzione è creare un set di indici per ogni combinazione di punti utilizzando la funzione MESHGRID. È quindi possibile tracciare ogni riga utilizzando la funzione di LINE (che riporta una riga per ogni colonna di dati è dato):
N = 10; %# Number of points
x = rand(1,N); %# A set of random x values
y = rand(1,N); %# A set of random y values
[I,J] = meshgrid(1:N); %# Create all the combinations of indices
index = [I(:) J(:)].'; %'# Reshape the indices
line(x(index),y(index),'Color','k'); %# Plot the lines
hold on
plot(x,y,'r*'); %# Plot the points
EDIT:
si può notare che la soluzione di cui sopra sarà tracciare una linea per ogni connessione, il che significa che traccerà linee su punti di connessione a lunghezza zero e tracciaerà 2 linee per ogni connessione (ad esempio dal punto A al punto B e dal punto B al punto A). Ecco un'altra soluzione (utilizzando le funzioni HANKEL e FIND) che non tracciare le linee ridondanti o inutili:
N = 10; %# Number of points
x = rand(1,N); %# A set of random x values
y = rand(1,N); %# A set of random y values
[r,c,v] = find(hankel(2:N)); %# Create unique combinations of indices
index = [v c].'; %'# Reshape the indices
line(x(index),y(index),'Color','k'); %# Plot the lines
hold on
plot(x,y,'r*'); %# Plot the points
Entrambe le soluzioni sopra creano piazzole visivamente identici:
A nota sul tempismo ...
Per curiosità, ho pensato di passare il tempo alla mia soluzione HANKEL e confrontare con Amro's soluzione molto tersa NCHOOSEK. Per N = 10
, non c'era alcuna differenza apprezzabile. Tuttavia, come ho aumentato N
a valori molto più grandi ho cominciato a vedere l'inizio soluzione NCHOOSEK a diventare molto lento:
N = 200
>> tic; [r,c,v] = find(hankel(2:N)); index = [v c].'; toc; %' Elapsed time is 0.009747 seconds. >> tic; pairs = nchoosek(1:N,2).'; toc; %' Elapsed time is 0.063982 seconds.
N = 1000
>> tic; [r,c,v] = find(hankel(2:N)); index = [v c].'; toc; %' Elapsed time is 0.175601 seconds. >> tic; pairs = nchoosek(1:N,2).'; toc; %' Elapsed time is 12.523955 seconds.
Sono stato un po 'sorpreso, fino a quando ho esaminato il codice per NCHOOSEK (digitando type nchoosek
nella finestra di comando MATLAB). Non solo una variabile viene sviluppata all'interno di un ciclo invece di essere preallocated (come Amro ha sottolineato in un commento), ma l'algoritmo utilizzato è anche ricorsivo, il che significa che vengono effettuate molte chiamate di funzione. Ho anche notato questa riga alla fine del testo di aiuto per NCHOOSEK:
Questa sintassi è utile solo in situazioni in cui N è inferiore a circa 15.
Sulla esempio s' gnovice, un modo più intuitivo semplice di generare tutte le coppie utilizza la funzione nchoosek:
%# random points
N = 10;
x = rand(1,N);
y = rand(1,N);
%# all possible combinations of the elements of [1:N] taken 2 at a time
pairs = nchoosek(1:N, 2)';
%'# plot points and lines
plot(x(pairs), y(pairs), '-bs', 'MarkerFaceColor','g', 'MarkerSize',10)
+1: Molto bello! Non avevo realizzato che NCHOOSEK potesse essere usato in quel modo. – gnovice
Mi sono ricordato di averlo letto in questo eccellente articolo del blog "Introduzione alla Combinatoria": http://blinkdagger.com/matlab/matlab-a-introduction-to-combinatorics/ – Amro
Per curiosità, ho fatto un po 'di tempistiche delle nostre soluzioni per 'n'. L'ho aggiunto alla mia risposta e sono rimasto sorpreso dai risultati. Noti la stessa cosa? – gnovice
funzionava bene grazie! –
Si potrebbe anche aggiungere il test: 'N = 1000; pairs = zeri (2,499500); k = 0; per i = 1: N, per j = i + 1: N, k = k + 1; coppie (:, k) = [j; i]; fine, fine' per mostrare la differenza con la versione non vettorializzata (la soluzione HANKEL è ancora più veloce!) – Amro