Pregunta

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:

example1
(fuente: WRIGHTRESULT.COM)

example2

example3
(fuente: twit88.com)

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

¿Fue útil?

Solución

Aquí hay una forma en que puedes hacer lo que quieras. Primero, genere puntos en el círculo que le interese

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 de otros cálculos, y encuentra los índices de los nodos conectados de eso. Aquí, he creado una matriz booleana de conexiones. Entonces, si hay N nodos, la matriz de conectividad es una NxN matriz simétrica, donde si el i,jEl elemento es 1, significa que tienes una conexión desde el nodo i al nodo j y 0 de lo contrario. Luego 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 que generé con el código anterior.

enter image description here

Ahora solo necesitamos trazar las conexiones, una 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 figura similar a sus ejemplos

enter image description here

Otros consejos

Inspirado en lo último entrada en el blog por Cleve Moler, también podrías usar el gplot función para dibujar un gráfico dado una matriz de adyacencia y coordenadas de nodo.

Aquí hay un ejemplo usando bucky; Una parte de demostración de MATLAB que genera el gráfico de un icosaedro truncado (parece una pelota de fútbol). Solo usaremos su matriz de adyacencia para este ejemplo, ya que estamos diseñando 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


Podemos dar un paso más allá e intentar minimizar los cruces de borde. 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 al encontrar un simétrico permutación de la matriz que minimiza su ancho de banda (los no jeroes 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 reemplazar líneas rectas con splines curvos para dibujar los bordes (de esa manera obtienes un gráfico más agradable similar al segundo que has mostrado), o usar diferentes colores para mostrar grupos de vértices y sus bordes (obviamente tú Necesita agrupar gráficos). Te dejaré esos pasos :)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top