我想创建一个图表,显示来自邻接矩阵的节点之间的连接,如下所示。
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使用某种algorithm自动找出一组看起来没问题的坐标所以我可以绘制一些看起来像顶部的图片。
提前致谢。
答案 0 :(得分:5)
一种方法是使用某种类型的静电排斥来编写自己的算法,如您链接的纸张。可能可以在少于40行的Matlab中完成(似乎others have tried)。但有时,使用外部工具比在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;
}
最后是一个图像 test.png (请注意,您的邻接矩阵列出了第一个项目与其自身的连接,显示为节点A处的循环):
作为一个更复杂的例子,您可以在gplot
的文档中绘制巴基球:
[A, XY] = bucky;
nodes = arrayfun(@(i) num2str(i), 1:size(A,1), 'uni', 0);
结果(注意布局是由neato完成的,它不使用XY
):
答案 1 :(得分:5)
自R2015b起,MATLAB现在拥有一套图形和网络算法。对于此示例,您可以create an undirected graph object然后使用overloaded plot
function:
% 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);
答案 2 :(得分:1)
如果连接图形,构造数组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
找到