Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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:

enter image description here

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!

share|improve this question
add comment

3 Answers

up vote 13 down vote accepted

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}  

enter image description here

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

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

\begin{document}

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

\end{document} 

enter image description here

share|improve this answer
    
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
add comment

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}

enter image description here

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

With your loop:

\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:

enter image description here

share|improve this answer
    
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
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.