4

I have the following code, a minimal working example only with 10 points:

\documentclass{article}
\usepackage{tikz,pgfplots}
\usetikzlibrary{calc}
\usetikzlibrary{positioning}

\begin{document}


\begin{tikzpicture}
    \begin{axis}[
        axis lines=middle,
        grid,
        xmin=-6, xmax=6,
        ymin=-6, ymax=6,
        scale=1.2]
        \addplot[only marks, color=blue,mark=*] coordinates {
          (0,-1) %Point 1
          (1,-1) %Point 2
          (-2,3) %Point 3
          (5,-5) %Point 4
          (-4,4) %Point 5
          (4,1) %Point 6
          (4,2) %Point 7
          (0,-5) %Point 8
          (0,5) %Point 9
          (2,0) %Point 10
        };
        \addplot[mark=,red] coordinates {(0,-1) (-2,3) (-4,4) (4,2) (0,5)}; %Conecting the points 1-3-5-7-9
    \end{axis}
\end{tikzpicture}

\end{document}

whose result is this figure:

enter image description here

My intention is to plot 50-100 points. This is ok. However, I want to conect different points whose information is contained in the adjacency matrix:

 0  0  1  1  0  1  0  0  1  0
 1  0  1  0  1  0  0  1  0  1
 0  0  0  0  1  1  0  0  0  0
 1  1  1  0  1  1  0  0  1  1
 1  0  0  0  0  0  0  1  0  0
 1  1  0  0  0  0  1  1  1  1
 0  1  1  1  0  0  0  1  1  0
 0  1  1  0  1  0  0  0  1  0
 1  1  1  1  1  1  1  1  0  1
 0  0  0  0  1  1  0  0  1  0

e.g., A[i,j] = 1 if there is a edge between points i and j and 0 otherwise; for example, there is edge between 1 and 3,4,6, and 9 and so on.

How can I implement in tikz, pgfplots or tikzmath this points (whose coordinates I provide) and the edges provided in the adjacency matrix (also given)? I dont want to draw each edge individualy, as done in the minimal example.

I thank very much for the help.

4
  • But what are coordinates of the points? Adjacency matrix only shows the connection but not the coordinates.
    – Sigur
    Commented Jul 13, 2022 at 1:48
  • The coordinates are given in Axis environment. Work with the given 10 points in the minimal example. Commented Jul 13, 2022 at 2:07
  • This cannot be done the same way you did in your example. You drew a single line through all your desired points. You can use your adjacency matrix and two foreach loops to draw a segment between two points each time it is needed.
    – SebGlav
    Commented Jul 13, 2022 at 9:43
  • Since you have asked 52 questions so far but never accepted any answer, please catch up (see How do you accept an answer?). This shows which answer helped you most, and it assigns reputation points to the author of the answer (and to you!). It's part of this site's idea to identify good questions and answers through upvotes and acceptance of answers.
    – dexteritas
    Commented Jul 13, 2022 at 19:15

1 Answer 1

3

I am not sure that everything is working as expected, but this could be something to get you started (sorry for not using the set-up of your MWE):

\documentclass[border=1mm]{standalone}
\usepackage{tikz, pgfplots}

\pgfplotstableread{
 x   y
 0  -1  
 1  -1  
-2   3  
 5  -5  
-4   4  
 4   1  
 4   2  
 0  -5  
 0   5  
 2   0  
}\nodesdefs

\pgfplotstableread[header=false]{
0  0  1  1  0  1  0  0  1  0  
1  0  1  0  1  0  0  1  0  1  
0  0  0  0  1  1  0  0  0  0  
1  1  1  0  1  1  0  0  1  1  
1  0  0  0  0  0  0  1  0  0  
1  1  0  0  0  0  1  1  1  1  
0  1  1  1  0  0  0  1  1  0  
0  1  1  0  1  0  0  0  1  0  
1  1  1  1  1  1  1  1  0  1  
0  0  0  0  1  1  0  0  1  0  
}\edgesdefs

\begin{document}

\begin{tikzpicture}

\begin{axis}

% Count the number of rows of the nodes matrix
% (needed for adding coordinates)
\pgfplotstablegetrowsof{\nodesdefs}
\pgfmathtruncatemacro\NodeRows{\pgfplotsretval-1} 

% In a first cycle plot all the nodes from the list and 
% attach a coordinate to it for later reference
\addplot[only marks] table[x=x, y=y] {\nodesdefs}
    \foreach \i in {0,...,\NodeRows} {
        coordinate [pos=\i/\NodeRows] (a\i)
    };

\end{axis}

% Count the number of rows and columns of the edges matrix
\pgfplotstablegetcolsof{\edgesdefs}
\pgfmathtruncatemacro\EdgeCols{\pgfplotsretval-1} 

\pgfplotstablegetrowsof{\edgesdefs}
\pgfmathtruncatemacro\EdgeRows{\pgfplotsretval-1} 

% For each item in the edges matrix, check whether it is 1 or 0;
% if it is 1, draw a line between the relevant coordinates
\foreach \x in {0,...,\EdgeRows}{
  \foreach \y in {0,...,\EdgeCols}{
    \pgfplotstablegetelem{\x}{[index]\y}\of{\edgesdefs}
    \ifnum\pgfplotsretval=1
        \draw (a\x) -- (a\y);
    \fi
  }
}

\end{tikzpicture}

\end{document}

enter image description here

Testing the result only for the first row of the edges matrix:

\pgfplotstableread[header=false]{
0  0  1  1  0  1  0  0  1  0  
}\edgesdefs

enter image description here

Looks correct to me: Node 1 (0,-1) connects to nodes 3, 4, 6 and 9 with coordinates (-2,3), (5,-5), (4,1) and (0,5) respectively.


A short (or maybe not so short) note regarding coordinate [pos=\i/\NodeRows] (a\i) which may be difficult to understand: Imagine a plot that is drawn by PGF/TikZ as one long line. This line may be bent or have edges, but it still is one line that goes through the several coordinates defined by the list of coordinates. Now, let's say you have 10 coordinates defined, then you can essentially go to the point on this line where the first coordinate sits with the statement [pos=0.1], because 1 divided by 10 is 0.1. This way, I used the pos option to go along the plotted path and attach the coordinates at the correct positions.


Edit:

Another way without the need to give an adjacency table could be as follows. Instead of the adjacency table, you just give a list of nodes to connect (for example 3,4,6,8) for the row that represents the relevant node (that is, the first row would represent the first node).

\documentclass[border=1mm]{standalone}
\usepackage{tikz, pgfplots}

\pgfplotstableread{
 x   y
 0  -1  
 1  -1  
-2   3  
 5  -5  
-4   4  
 4   1  
 4   2  
 0  -5  
 0   5  
 2   0  
}\nodesdefs

\pgfplotstableread[header=false]{
3,4,6,8
3,5
}\edgesdefs

\begin{document}

\begin{tikzpicture}

\begin{axis}

% Count the number of rows of the nodes matrix
% (needed for adding coordinates)
\pgfplotstablegetrowsof{\nodesdefs}
\pgfmathtruncatemacro\NodeRows{\pgfplotsretval-1} 

% In a first cycle plot all the nodes from the list and 
% attach a coordinate to it for later reference
\addplot[only marks] table[x=x, y=y] {\nodesdefs}
    \foreach \i in {0,...,\NodeRows} {
        coordinate [pos=\i/\NodeRows] (a\i)
    };

\end{axis}

% Count the number of rows of the edges matrix
\pgfplotstablegetrowsof{\edgesdefs}
\pgfmathtruncatemacro\EdgeRows{\pgfplotsretval-1} 

% For each item in the edges matrix, check whether it is 1 or 0;
% if it is 1, draw a line between the relevant coordinates
\foreach \x in {0,...,\EdgeRows}{
  \pgfplotstablegetelem{\x}{[index]0}\of{\edgesdefs}
  \foreach \y in \pgfplotsretval{
    \draw (a\x) -- (a\y);
  }
}

\end{tikzpicture}

\end{document}

enter image description here

2
  • R­e­a­lly neat!
    – antshar
    Commented Jul 13, 2022 at 11:59
  • I added an explanation regarding [pos=\i/\NodeRows]. As for the question whether one could replace the adjecency matrix by something like 1-3-5-7-8: well, this would work. But then the code would need to be a bit different of course ... Commented Jul 13, 2022 at 13:17

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .