我有一个社交网络图,是使用图形对象在 Matlab 中制作的:
G = graph(weight);
LWidths = 10*G.Edges.Weight/max(G.Edges.Weight);
h = plot(G,'NodeLabel',cellstr(screen_names),'LineWidth',LWidths);
for i = 1:nnodes
highlight(h,i, 'MarkerSize', counts(i))
end
其中weight
是邻接矩阵,counts
是带有节点大小的向量。它看起来像这样:
现在,我对它的外观不满意,所以我想用 Tikz 来制作它。所以我的问题是:是否可以使用 Tikz 从邻接矩阵生成这种类型的图形,其中边缘的宽度不同,被视为矩阵的非零元素。节点的大小也应该不同。我对 Tikz 不是很有经验,因此任何有关如何进行的指导都将不胜感激。
我读过了这篇类似的帖子,但我仍然不确定如何处理不同的边宽和节点大小。此外,是否需要明确给出节点的坐标,还是可以像在 Matlab 中一样自动生成?
矩阵如下weight
:
weight =
0 741 630 406 325 325 351 0 300 276
741 0 406 351 276 0 0 0 0 0
630 406 0 300 0 276 300 0 0 0
406 351 300 0 0 0 0 0 0 0
325 276 0 0 0 0 0 0 0 0
325 0 276 0 0 0 276 0 0 0
351 0 300 0 0 276 0 0 0 0
0 0 0 0 0 0 0 0 0 0
300 0 0 0 0 0 0 0 0 0
276 0 0 0 0 0 0 0 0 0
和counts
向量:
counts =
56 42 39 34 32 31 30 29 28 28
答案1
有点粗糙,但可以正常工作,并且需要lualatex
。一个简单的解析器(仅匹配非空白)加上一个图形绘制宏。
\RequirePackage{luatex85}
\documentclass[tikz,border=5]{standalone}
\usetikzlibrary{graphs,graphdrawing}
\usegdlibrary{force,trees}
\usepackage{luacode}
\begin{luacode*}
function parseNetwork(nodeWeights, adjacencyMatrix)
local i, j, n, v, w, str
n = 0
weights = {}
for str in string.gmatch(nodeWeights, "[^%s]+") do
w = tonumber(str)
tex.print("n" .. n + 1 .. "/[minimum size=" .. w .. ", label=center:node" .. n + 1 .. "];")
n = n + 1
end
i = 0
j = 0
for str in string.gmatch(adjacencyMatrix, "[^%s]+") do
v = tonumber(str)
if v > 0 then
if j > i then
tex.print("n" .. i + 1 .. " --[line width=" .. (v / 100) .. "]" .. "n" .. j + 1 .. ";")
end
end
j = (j + 1) % n
if j == 0 then i = i + 1 end
end
end
\end{luacode*}
\tikzgraphsset{%
node weights/.store in=\nodeweights,
adjacency matrix/.store in=\adjacencymatrix,
declare={network}{
[/utils/exec={%
\edef\networkspec{\directlua{parseNetwork("\nodeweights","\adjacencymatrix")}}},
parse/.expanded=\networkspec]
}}
\begin{document}
\begin{tikzpicture}
\graph [spring electrical layout,
edges={draw=blue!50!cyan, shorten >=-1em, shorten <=-1em},
nodes={circle, fill=blue!50!cyan!50},
electric charge=10]{
network [
node weights={
56 42 39 34 32 31 30 29 28 28
},
adjacency matrix={
0 741 630 406 325 325 351 0 300 276
741 0 406 351 276 0 0 0 0 0
630 406 0 300 0 276 300 0 0 0
406 351 300 0 0 0 0 0 0 0
325 276 0 0 0 0 0 0 0 0
325 0 276 0 0 0 276 0 0 0
351 0 300 0 0 276 0 0 0 0
0 0 0 0 0 0 0 0 0 0
300 0 0 0 0 0 0 0 0 0
276 0 0 0 0 0 0 0 0 0
}];
};
\end{tikzpicture}
\end{document}