繁体   English   中英

如何使用MATLAB绘制邻接矩阵图

[英]How to graph adjacency matrix using MATLAB

我想创建一个图表,显示来自邻接矩阵的节点之间的连接,如下所示。

在此输入图像描述

gplot似乎是最好的工具。 但是,为了使用它,我需要传递每个节点的坐标。 问题是我不知道坐标应该在哪里,我希望这个函数能够为我找出一个好的布局。

例如,这是我的输出使用以下任意坐标:

 A = [1 1 0 0 1 0;
      1 0 1 0 1 0;
      0 1 0 1 0 0;
      0 0 1 0 1 1;
      1 1 0 1 0 0;
      0 0 0 1 0 0];

 crd = [0 1;
        1 1;
        2 1;
        0 2;
        1 2;
        2 2];

 gplot (A, crd, "o-");

在此输入图像描述

这很难读,但是如果我稍微使用坐标并将它们更改为以下内容就会变得更具可读性。

   crd = [0.5 0;
         0 1;
         0 2;
         1 2;
         1 1;
         1.5 2.5];

在此输入图像描述

我不希望完美优化的坐标或任何东西,但我怎么能告诉MATLAB自动为我找出一组坐标看起来没问题使用某种算法,所以我可以绘制看起来像顶部图片的东西。

提前致谢。

一种方法是使用某种静电排斥来编写自己的算法,就像你链接的文章一样。 可能可以在少于40行的Matlab中完成(似乎其他人已经尝试过 )。 但有时,使用外部工具比在Matlab中完成所有工作更好。 绘制图形的最佳工具可能是Graphviz ,它附带了一套用于绘制不同样式图的工具。 对于无向图,要使用的是neato 我不知道它用于分配节点的算法,但我想它与你的论文中的类似(其中一个参考文献甚至提到了Graphviz!)。

这些工具的输入是一种非常简单的文本格式,使用Matlab很容易生成。 示例(这适用于Linux,您可能需要在Windows上稍微更改一下):

% adjacency matrix
A = [1 1 0 0 1 0;
     1 0 1 0 1 0;
     0 1 0 1 0 0;
     0 0 1 0 1 1;
     1 1 0 1 0 0;
     0 0 0 1 0 0];

% node labels, these must be unique
nodes = {'A', 'B', 'C', 'D', 'E', 'F'};

n = length(nodes);
assert(all(size(A) == n))

% generate dot file for neato
fid = fopen('test.dot', 'w');
fprintf(fid, 'graph G {\n');
for i = 1:n
    for j = i:n
        if A(i, j)
            fprintf(fid, '    %s -- %s;\n', nodes{i}, nodes{j});
        end
    end
end
fprintf(fid, '}\n');
fclose(fid);

% render dot file
system('neato -Tpng test.dot -o test.png')

这产生文件test.dot

graph G {
    A -- A;
    A -- B;
    A -- E;
    B -- C;
    B -- E;
    C -- D;
    D -- E;
    D -- F;
}

最后是一个image test.png (注意你的邻接矩阵列出了第一个项目与自身的连接,它显示为节点A的循环):

在此输入图像描述

作为一个更复杂的例子,你可以在gplot的文档中绘制一个gplot球:

[A, XY] = bucky;
nodes = arrayfun(@(i) num2str(i), 1:size(A,1), 'uni', 0);

结果(注意布局是由neato完成的,它不使用XY ):

在此输入图像描述

从R2015b开始,MATLAB现在拥有一套图形和网络算法。 对于此示例,您可以创建无向图对象 ,然后使用重载plot函数绘制它:

% Create symmetric adjacency matrix
A = [1 1 0 0 1 0;
     1 0 1 0 1 0;
     0 1 0 1 0 0;
     0 0 1 0 1 1;
     1 1 0 1 0 0;
     0 0 0 1 0 0];
% Create undirected graph object
G = graph(A);
% Plot
plot(G);

使用MATLAB的图形/绘图功能创建的布局

如果你的图是连通的,那么构造数组xy以传递给gplot的方法是v(:,[2 3])其中v是拉普拉斯矩阵的特征向量矩阵,从最小特征值到最大特征值排序。 所以我们可以这样做:

L=diag(sum(A))-A;
[v,~]=eig(L);
xy=v(:,[2 3])
gplot(A,xy)

或者这样:

L=diag(sum(A))-A;
[v,~]=eigs(L,3,'SM')
xy=v(:,[2 1])
gplot(A,xy)

第二个应该更有效率,特别是如果A很大。

这将在正常情况下创建一个漂亮的情节。 这不能保证工作; 特别是,不能保证为不同的节点分配不同的坐标。 但通常它的效果非常好。

这背后的一些理论可以在https://arxiv.org/pdf/1311.2492.pdf找到

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM