Domanda

Vorrei tracciare un grafico circolare di nodi in cui alcuni nodi hanno un legame tra di loro. Ecco alcuni esempi di grafici di rete sociale:

esempio1
(fonte: wrightresult.com )

example2

esempio3
(fonte: twit88.com )

Come può questo essere fatto con MATLAB? E 'possibile senza l'installazione di un pacchetto separato?

È stato utile?

Soluzione

Ecco un modo che si può fare quello che vuoi. In primo luogo, generare punti sul cerchio che siete interessati in

clear;
theta=linspace(0,2*pi,31);theta=theta(1:end-1);
[x,y]=pol2cart(theta,1);

Quindi, se si conoscono le coppie di nodi che sono collegati, è possibile saltare questo passaggio. Ma in molti casi, si ottiene una matrice di connettività da altri calcoli, e trovare gli indici dei nodi collegati da questo. Qui, ho creato una matrice booleana di connessioni. Quindi, se ci sono nodi N, la matrice connettività è una matrice simmetrica NxN, dove se l'elemento i,jth è 1, significa che dispone di una connessione dal nodo i al nodo j e 0 altrimenti. È quindi possibile estrarre i pedici dei non-zero coppie di ottenere connessioni dei nodi (è necessario solo triangolo superiore).

links=triu(round(rand(length(theta))));%# this is a random list of connections
[ind1,ind2]=ind2sub(size(links),find(links(:)));

Questa è la matrice connettività I generato con il codice di cui sopra.

entrare descrizione dell'immagine qui

Ora abbiamo solo bisogno di tracciare le connessioni, una alla volta

h=figure(1);clf(h);
plot(x,y,'.k','markersize',20);hold on
arrayfun(@(p,q)line([x(p),x(q)],[y(p),y(q)]),ind1,ind2);
axis equal off

che vi darà una figura simile ai vostri esempi

entrare descrizione dell'immagine qui

Altri suggerimenti

Ispirato l'ultima post da Cleve Moler, si potrebbe anche utilizzare la funzione gplot per disegnare un grafico riportato un adiacenze matrice e nodo coordinate.

Ecco un esempio utilizzando bucky ; una parte la funzione demo di MATLAB che genera il grafico di un'icosaedro troncato (sembra un pallone da calcio). Useremo solo la matrice di adiacenza per questo esempio poiché stiamo tracciando i vertici in una forma circolare:

%# 60-by-60 sparse adjacency matrix
A = bucky();
N = length(A);

%# x/y coordinates of nodes in a circular layout
r =  1;
theta = linspace(0,2*pi,N+1)'; theta(end) = [];
xy = r .* [cos(theta) sin(theta)];

%# labels of nodes
txt = cellstr(num2str((1:N)','%02d'));

%# show nodes and edges
line(xy(:,1), xy(:,2), 'LineStyle','none', ...
    'Marker','.', 'MarkerSize',15, 'Color','g')
hold on
gplot(A, xy, 'b-')
axis([-1 1 -1 1]); axis equal off
hold off

%# show node labels
h = text(xy(:,1).*1.05, xy(:,2).*1.05, txt, 'FontSize',8);
set(h, {'Rotation'},num2cell(theta*180/pi))

circular_graph


Possiamo prendere questo un ulteriore passo avanti e cercare di minimizzare incroci tra archi. Cioè vogliamo riorganizzare i nodi in modo che i bordi siano il più vicino possibile alla circonferenza del cerchio.

Questo può essere fatto trovando un simmetrica permutazione della matrice che riduce al minimo sua larghezza di banda (non-zero sono più vicini alla diagonale)

matrix_permutation

p = symrcm(A);
A = A(p,p);
txt = txt(p);

Il risultato in questo caso:

circular_graph_permutation

Altri miglioramenti includono la sostituzione rette con curve spline per disegnare i bordi, (in questo modo si ottiene un grafico migliore simile alla seconda hai mostrato), o utilizzando colori diversi per mostrare gruppi di vertici e loro bordi (ovviamente avrete bisogno di fare il grafico di clustering). Lascerò quei passi per voi:)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top