2011-04-27 126 views
13

我想绘制一个节点的圆形图,其中某些节点之间有链接。以下是社交网络图的几个例子:绘制一个圆形节点的网络节点之间的链接

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

怎么可以这样用MATLAB做什么?有没有可能没有安装一个单独的包?

+0

可能的重复[如何在MATLAB中将相关矩阵可视化为模态球](http://stackoverflow.com/questions/17038377/how-to-visualize-correlation-matrix- as-a-scheballball-in-matlab) – Shai 2013-06-13 19:05:21

回答

13

这里有一种方法可以做你想做的。首先,产生对你有兴趣

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

接下来,如果你知道连接节点的对,你可以跳过这一步的圆点。但是在很多情况下,您可以从其他计算中获得连接矩阵,并且可以从中找到连接节点的索引。在这里,我创建了一个布尔连接矩阵。所以,如果有N节点,连接矩阵是NxN对称矩阵,其中如果i,j个元素是1,这意味着你有从节点i到节点j0否则的连接。然后,您可以提取非零对的下标以获取节点连接(只需要上三角形)。

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

这是我用上面的代码生成的连接矩阵。

enter image description here

现在我们只需要绘制的连接,一次一个

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 

,这将给你一个类似于数字到你的例子

enter image description here

+3

不错,但你打给[ARRAYFUN](http://www.mathworks.com/help/techdoc/ref/arrayfun.html)的电话是不必要的。如果为X和Y数据输入矩阵,则可以使用[PLOT](http://www.mathworks.com/help/techdoc/ref/plot.html)和[LINE](http://www.mathworks。 com/help/techdoc/ref/line.html)会自动绘制每列一行。所以你可以这样绘制连接:'plot([x(ind1); x(ind2)],[y(ind1); y(ind2)],'b');' – gnovice 2011-04-27 15:52:37

+2

@gnovice:是的,我意识到这一点。我使用'arrayfun'是因为我不确定OP是否只是提升绘图命令并直接在他的程序中使用或者在这里遵循整个代码。如果他已经初始化了他的节点向量和连接索引作为我在这里的转置,并且只是使用了SO的绘图功能,那么使用'plot()'可能会导致一条连接线遍布整个地方,而不是一条线每对,而'arrayfun'仍然会一对一对。但是,是的,如果OP与他的媒介一致,那么'plot()'是要走的路。 – abcd 2011-04-27 16:09:58

4

的灵感Cleve Moler最新的blog post,你也可以使用gplot fu绘制给定邻接矩阵和节点坐标的图。

这是一个使用bucky的示例; MATLAB的一个演示函数部分,它生成一个截断的二十面体图形(看起来像一个足球)。

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


我们可以借此更进一步,尽量减少边交叉:因为我们是在一个圆形布局的顶点,我们将只使用它的邻接矩阵在这个例子中。那就是我们要重新排列节点,使边缘尽可能接近圆的圆周。

这可以通过发现它的带宽最小化矩阵的对称permutation进行(非零更靠近对角线)

matrix_permutation

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

结果在这种情况下:

circular_graph_permutation

其他改进包括用c代替直线(用这种方法可以得到类似于第二个图的更好的图),或者使用不同的颜色来显示顶点和边的聚类(显然你需要做图聚类)。我会离开这些步骤给你:)

相关问题