Disegno di una rete di nodi in formazione circolare con collegamenti tra i nodi
-
24-10-2019 - |
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:
(fonte: wrightresult.com )
(fonte: twit88.com )
Come può questo essere fatto con MATLAB? E 'possibile senza l'installazione di un pacchetto separato?
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,j
th è 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.
Ora abbiamo solo bisogno di tracciare le connessioni, una alla volta ??p>
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
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))
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)
p = symrcm(A);
A = A(p,p);
txt = txt(p);
Il risultato in questo caso:
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:)