0

I have the adjacency matrix for a directed weighted graph. I want to draw this graph in tikz. My adjacency matrix is of size 50 by 50 and I have it in txt format. Obviously it is better to have code that uses the txt file and also positions the nodes automatically since I don't have the positions. Thanks for the help!

  • 2
    Draw 50 nodes in a circle and connect them where necessary. – Paul Gaborit Apr 05 '22 at 12:43
  • 1
    Having a 50 nodes graph would be pretty unlegible but anyway, it's possible. You may draw an edge wherever the weight is different from zero, so it's just a question of \if ... \fi but it's hard to help you without anything to start with. Please edit your post with a minimal working example (MWE). – SebGlav Apr 05 '22 at 19:40

1 Answers1

1

Fifty nodes are going to be a mess but here's a start for nine.

For the real usage remove the line commented with fake and uncomment real which actually sets the weights given by the weights/matrix, e.g.

weights/matrix={{1,2,3},{4,5,6},{7,8,9}}

for the 3×3 matrix

1 2 3
4 5 6
7 8 9


This is obviously not legible but I'm open for suggestions.
No rotation? White background? Line width? Dash pattern? Color?

With the graphdrawing library, maybe a better layout can be achieved, especially if a lot of edges have a weight of zero.

Code

\documentclass[tikz]{standalone}
\usepackage{amsmath}% for \overset
\usetikzlibrary{
  graphs.standard, % for \graph and subgraph I_n
  quotes,          % "nodes" on edges
  ext.misc}        % for /utils/TeX/ifnum
\tikzset{
  weights/matrix/.style={
    /utils/exec=\def\listrow{0},
    /utils/rows/.style={
      /utils/exec=\def\listcol{0}\edef\listrow{\the\numexpr\listrow+1\relax},
      /utils/cols/.estyle={/utils/exec=\edef\noexpand\listcol{\noexpand\the\numexpr\noexpand\listcol+1\relax},
        /tikz/weights/weight \listrow-\noexpand\listcol/.initial/.evaluated={random(0,9)}% fake
%        /tikz/weights/weight \listrow-\noexpand\listcol/.initial={####1}% real
      }, /utils/cols/.list={##1},
    }, /utils/rows/.list={#1}}}
\begin{document}
\begin{tikzpicture}[
  weights/matrix={% include actual weights here
    {,,,,,,,,},
    {,,,,,,,,},
    {,,,,,,,,},
    {,,,,,,,,},
    {,,,,,,,,},
    {,,,,,,,,},
    {,,,,,,,,},
    {,,,,,,,,},
    {,,,,,,,,}},
]
\graph [
  clockwise, % place nodes in a circle
  radius=5cm,% of this radius
  nodes={circle, draw},
  do edge/.style 2 args={
    % if the weight is 0 → ignore edge
    /utils/TeX/ifnum={\pgfkeysvalueof{/tikz/weights/weight #1-#2}=0}{}{
      /utils/TeX/ifnum={#1=#2}{
        % if row = col → just add label
        parse={#1[label={[anchor=west]west:%
          \pgfkeysvalueof{/tikz/weights/weight #1-#2}}]}
      }{% otherwise draw edge and add weight as a label
        parse={#1 --[
          "$#1\overset{\pgfkeysvalueof{/tikz/weights/weight #1-#2}}{\to}#2$"{
            sloped, allow upside down}] #2}}}}
]{
  subgraph I_n[n=9];
  {[
    /tikz/every node/.append style={font=\scriptsize, inner ysep=+.4ex},
    /tikz/every label/.append style={inner sep=+.1em},
  ] \foreach \row in {1,...,9} {
      \foreach \col in {1,...,9} {
        [do edge=\row\col]}}}};
\end{tikzpicture}
\end{document}

Output

enter image description here

Qrrbrbirlbel
  • 119,821
  • Of course, storing the matrix in value-keys isn't necessary, we can use them directly in the loops in the graphs. And with pgfplotstable we can use the loops provided by the package to loop over the rows and columns in an external file. – Qrrbrbirlbel Oct 24 '22 at 08:45