# TikZ: Using Loop to Draw Grid of Nodes

I am trying to draw an Ising model (in my case, a grid of nodes with an undirected edge between adjacent nodes on the same row or column) using TikZ. I have the grid of nodes working nicely using a foreach loop, but I am having trouble drawing the lines between nodes. The problem lies in the fact that I am getting a syntax error when I try to \draw lines between computed node names.

Here is what I have so far:

Here is the code I am using:


\documentclass{minimal}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\scriptsize
\foreach \i in {1,...,25}
{
\pgfmathtruncatemacro{\y}{(\i - 1) / 5};
\pgfmathtruncatemacro{\x}{\i - 5 * \y};
\pgfmathtruncatemacro{\label}{\x + 5 * (4 - \y)};
\node[circle,draw=black,fill=white!80!black,minimum size=20]
(\label) at (1.5*\x,1.5*\y) {\label};
}
% These draw commands are working as intended.
\draw (1) -- (2);
\draw (1) -- (6);
\draw (6) -- (7);
\draw (7) -- (2);
% The loop, however, is not =(
%\foreach \x in {1,...,4}
%\foreach \y in {0,...,4}
%{
%       \pgfmathtruncatemacro{\cur}{\x + 5 * \y};
%       \pgfmathtruncatemacro{\next}{\cur + 1};
%       \draw (\cur) -- (\next);
%}
\end{tikzpicture}
\end{document}


Thank you very much for your help!

-

It's possible to use a minimum code

\documentclass{minimal}
\usepackage{tikz}

\begin{document}
\begin{tikzpicture}[darkstyle/.style={circle,draw,fill=gray!40,minimum size=20}]
\foreach \x in {0,...,4}
\foreach \y in {0,...,4}
{\pgfmathtruncatemacro{\label}{\x - 5 *  \y +21}
\node [darkstyle]  (\x\y) at (1.5*\x,1.5*\y) {\label};}

\foreach \x in {0,...,4}
\foreach \y [count=\yi] in {0,...,3}
\draw (\x\y)--(\x\yi) (\y\x)--(\yi\x) ;

\end{tikzpicture}
\end{document}


Only for information you can get the grid with tkz-berge

\documentclass[border=0.25cm]{standalone}
\usepackage{tkz-berge}

\begin{document}

\begin{tikzpicture}
\grGrid[Math,RA=2,RB=2]{5}{5}
\end{tikzpicture}

\end{document}


-
Thanks for the solution! Your tkz-berge package is very interesting, and seems to make certain operations a lot easier. I didn't think of using (\x\y) to create the label for the node, and resorted to using a single loop instead. –  void-pointer Jul 2 '12 at 5:49

\foreach \x in {1,...,4}
\foreach \y in {0,...,4}
{
\pgfmathtruncatemacro{\cur}{\x + 5* \y}
\pgfmathtruncatemacro{\next}{\cur + 1}
\draw (\cur) -- (\next);
}


you are actually drawing just horizontal lines. Thus, if I understood correctly the question, you need to draw vertical lines.

For simplicity I used another loop:

% Vertical connections
\foreach \start in {1,...,20}
{
\pgfmathtruncatemacro{\down}{\start+5}
\draw (\start) -- (\down);
}


Here is the full code:

\documentclass{minimal}
\usepackage{tikz}
\usetikzlibrary{positioning}

\tikzset{darkstyle/.style={circle,draw,fill=gray!40}}
\begin{document}
\begin{tikzpicture}
\foreach \i in {1,...,25}
{
\pgfmathtruncatemacro{\y}{(\i - 1) / 5}
\pgfmathtruncatemacro{\x}{\i - 5 * \y}
\pgfmathtruncatemacro{\label}{\x + 5 * (4 - \y)}
\node[darkstyle,minimum size=20] (\label) at (1.5*\x,1.5*\y)
{\label};
}

% Horizontal connections

\foreach \x in {1,...,4}
\foreach \y in {0,...,4}
{
\pgfmathtruncatemacro{\cur}{\x + 5* \y}
\pgfmathtruncatemacro{\next}{\cur + 1}
\draw (\cur) -- (\next);
}

% Vertical connections
\foreach \start in {1,...,20}
{
\pgfmathtruncatemacro{\down}{\start+5}
\draw (\start) -- (\down);
}

\end{tikzpicture}
\end{document}


The result is:

-
Actually, my code initially was not compiling! I was getting an error about 1) not being a shape, so thought that my foreach loop had incorrect syntax. I copy-pasted the code I put up again, and now it works. I wonder what I left out in my editor... –  void-pointer Jul 1 '12 at 8:56
That's probably due to a wrong initialization of one loop: when I copied your code to test I got no errors in compiling. –  Claudio Fiandrino Jul 1 '12 at 9:08
You can remove some unnecessary \pgfmathtruncatemacro for example \pgfmathtruncatemacro{\y}{(\i - 1) / 5}and you don't need to add ; at the end of \pgfmathtruncatemacro. It's not a tikz's command. –  Alain Matthes Jul 1 '12 at 9:48
I tried to follow the OP's MWE adding just the necessary code. Your solution is really nice and IMHO that's the one to be accepted. I'll edit my answer to remove the unnecessary ;. Thanks! –  Claudio Fiandrino Jul 1 '12 at 9:53
Altermundus's answer seems to be the most comprehensive, so I will change the accepted solution accordingly. –  void-pointer Jul 2 '12 at 5:46

As this looks like a grid, you could also use one (and probably two nested foreach loops for the node generation):

\documentclass{standalone}
\usepackage{tikz}

\begin{document}

\begin{tikzpicture}
\draw[step=1.5,thick] (0,-6) grid (6,0);
\foreach \x in {0,...,4}
{   \foreach \y in {0,...,4}
{   \pgfmathtruncatemacro{\nodelabel}{\x+\y*5+1}
\node[circle,draw=black,fill=white!80!black,minimum size=20] (\nodelabel) at (1.5*\x,-1.5*\y) {\nodelabel};
}
}
\end{tikzpicture}

\end{document}


-
Bien vu ! :) but you limit the action on the style of the edges with this method. –  Alain Matthes Jul 1 '12 at 9:54