2011-04-27 19 views
13

Me gustaría dibujar un gráfico circular de nodos donde ciertos nodos tienen un enlace entre ellos. Aquí hay algunos ejemplos de gráficos de redes sociales:Dibujando una red de nodos en formación circular con enlaces entre nodos

example1 http://wrightresult.com/wp-content/uploads/social-network-circle5-lg.jpg

example2

example3 http://twit88.com/blog/wp-content/uploads/2008/07/windowslivewriterjung-ed84jung-2.jpg

¿Cómo se puede hacer esto con MATLAB? ¿Es posible sin instalar un paquete separado?

+0

posible duplicado de [Cómo visualizar la matriz de correlación como schemaball en Matlab] (http://stackoverflow.com/questions/17038377/how-to-visualize-correlation-matrix- as-a-schemaball-in-matlab) – Shai

Respuesta

13

Aquí hay una manera de que pueda hacer lo que quiera. En primer lugar, generar puntos de la circunferencia que está interesado en

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

A continuación, si conoce los pares de nodos que están conectados, puede omitir este paso. Pero en muchos casos, obtienes una matriz de conectividad a partir de otros cómputos, y encuentras los índices de los nodos conectados a partir de eso. Aquí, he creado una matriz booleana de conexiones. Por lo tanto, si hay N nodos, la matriz de conectividad es una matriz simétrica NxN, en la que si el elemento es i,j º 1, significa que tiene una conexión desde el nodo a nodo ij y 0 lo contrario. A continuación, puede extraer los subíndices de los pares distintos de cero para obtener conexiones de nodo (solo se necesita el triángulo superior).

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

Esta es la matriz de conectividad I generados con el código de seguridad.

enter image description here

Ahora sólo tenemos que trazar las conexiones, uno a la vez

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 

que le dará una cifra similar a los ejemplos

enter image description here

+3

Bueno, pero su llamada a [ARRAYFUN] (http://www.mathworks.com/help/techdoc/ref/arrayfun.html) es innecesaria. Si ingresa matrices para los datos X e Y, funciones como [TRAZAR] (http://www.mathworks.com/help/techdoc/ref/plot.html) y [LÍNEA] (http: //www.mathworks. com/help/techdoc/ref/line.html) trazará automáticamente una línea por columna. Así que puedes trazar las conexiones de la siguiente manera: 'plot ([x (ind1); x (ind2)], [y (ind1); y (ind2)], 'b');' – gnovice

+2

@gnovice: sí, yo ' soy consciente de eso. Usé 'arrayfun' porque no estaba seguro de si el OP simplemente iba a levantar los comandos de trazado y usarlo directamente en su programa o seguir aquí el código completo. Si él había inicializado sus vectores de nodos e índices de conexión como la transposición de lo que tengo aquí, y acaba de usar las funciones de trazado de SO, usar 'plot()' puede dar como resultado una única línea conectada que está por todos lados, en lugar de una línea por par, mientras que 'arrayfun' seguirá haciéndolo par por par. Pero sí, si OP es consistente con sus vectores, 'plot()' es el camino a seguir. – abcd

4

Inspirado por el último blog post de Cleve Moler, también podría usar el gplot fu nction para dibujar un gráfico dado una matriz de adyacencia y coordenadas de nodo.

Aquí hay un ejemplo que usa bucky; una función de demostración de MATLAB que genera el gráfico de un icosaedro truncado (parece una pelota de fútbol). Sólo utilizaremos su matriz de adyacencia para este ejemplo ya que estamos poniendo a cabo los vértices en forma circular:

%# 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


nos puede llevar esto un paso más allá y tratar de minimizar cruceros de eje . Es decir, queremos reorganizar los nodos para que los bordes estén lo más cerca posible de la circunferencia del círculo.

Esto se puede hacer mediante la búsqueda de una simétrica permutation de la matriz que minimice su ancho de banda (no-ceros están más cerca de la diagonal)

matrix_permutation

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

El resultado en este caso:

circular_graph_permutation

Otras mejoras incluyen el reemplazo de líneas rectas con c urdió splines para dibujar los bordes, (de esa manera obtienes un gráfico más bonito similar al que has mostrado), o usando diferentes colores para mostrar los cúmulos de vértices y sus bordes (obviamente, necesitarás hacer un clúster de gráficos). Dejaré esos pasos para ti :)

Cuestiones relacionadas