5

My code is :

\begin{center}
    \begin{tikzpicture}
    \foreach \x in {0,...,11}
        \draw (\x,0) +(-0.5,-.5)rectangle +(0.5,0.5);
    \foreach \x/\val in {0/9,1/5,2/13,3/19,4/12,5/8,6/7,7/4,8/21,9/2,10/6,11/11}
        \draw (\x,0) node {\val} (\x,-0.85) node{{\footnotesize \x+1}};
    \draw[ultra thick] (0,0)++(-0.5,-.5) rectangle +(12,1);
    \end{tikzpicture}
\end{center}

The output is :

Output

I want the text at the nodes to be the value of (x+1), but all I get is the text. How do I get the values of 1 through 12 below the array to point out the indices?

5

One way is to use evaluate inside the \foreach loop:

\foreach \x/\val [evaluate=\x as \xx using \x+1] in {0/9,1/5,2/13,3/19,4/12,5/8,6/7,7/4,8/21,9/2,10/6,11/11} {
    \draw (\x,0) node {\val} (\x,-0.85) node{{\footnotesize \xx}};
}

This said, I would do this differently. First, you can have several commands inside a \foreach loop just by enclosing them in {...}, so you can get rid of one of the loops. Secondly, if you draw the nodes as rectangles this will take care of the line between adjacent boxes. Finally, since \x just counts the box you can "compute" this using \count, making the code easier to read and easier to write.

Putting this together gives:

\documentclass{article}
\usepackage{tikz}
\begin{document}

\begin{center}
  \begin{tikzpicture}[mybox/.style={rectangle, draw, 
                                    minimum width=10mm, minimum height=10mm}]
        \foreach \val [count=\x, remember=\x] in {9,5,13,19,12,8,7,4,21,2,6,11} {
            \node[mybox,label=below:{\footnotesize\x}] at (\x,0) {\val};
        }
        \draw[ultra thick] (0.5,-0.5) rectangle +(\x,1);
    \end{tikzpicture}
\end{center}

\end{document}

to produce:

enter image description here

Notice that I have shifted your "big" box so that it starts from (0.5,-0.5) so as to avoid having to add 1 to \x. Also, the mybox style takes care of the line between the boxes. The remmber in the \foreach loop is so that the last value of \x can be used after the loop for drawing the frame.

The rectangle,draw in the style command draws a rectangle around the border of node. If you leave out the minimum height and minimum width then size of the rectangle will be only big enough to contain the contents of the node, which means that the "boxes" for the nodes will have different sizes. Specifying the minimum height and minimum width ensures that we get square boxes. Indeed, if we leave out the minimum height and width then we get:

enter image description here

If you wanted to put this into a macro then you could use something like:

\documentclass{article}
\usepackage{tikz}
\begin{document}

\newcommand\boxes[1]{%
\begin{center}
  \begin{tikzpicture}[mybox/.style={rectangle, draw, minimum width=10mm, minimum height=10mm}]
    \foreach \val [count=\x, remember=\x] in {#1} {
        \node[mybox,label=below:{\footnotesize\x}] at (\x,0) {\val};
    }
    \draw[ultra thick] (0.5,-0.5) rectangle +(\x,1);
    \end{tikzpicture}
\end{center}
}

\boxes{9,5,13,19,12,8,7,4,21,2,6,11}

\boxes{9,5,13,19,1}

\end{document}

to give

enter image description here

  • What exactly is the purpose of using minimum width and minimum height? Sorry, if the explanation is obvious, I'm new to latex. – Somenath Sinha Nov 7 '16 at 6:00
  • 1
    I have edited my answer to explain what these do. Let me know if this doesn't make sense. – Andrew Nov 7 '16 at 6:24
  • Is there a way to automatically set the length of the "big box" as described here: \draw[ultra thick] (1,0)++(-0.5,-.5) rectangle +(12,1); to be set to the size of the internal box? i.e., If I put 5 elements into the array, the outer box should also adjust to the size of the array of 5 elements, instead of 12. – Somenath Sinha Nov 7 '16 at 7:03
  • 1
    node[mybox, label=below:{\footnotesize\x}] at (\x,0) {\val}; saves you from using/typing two nodes. – Ignasi Nov 7 '16 at 8:17
  • 1
    @SomenathSinha Yes. I thought about adding this earlier but forgot. You just need to add remember to the \foreach. Will edit and also incorporate Ignasi's improvement. – Andrew Nov 7 '16 at 9:55
3

An alternative solution with a matrix.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{matrix}

\begin{document}

\begin{center}
  \begin{tikzpicture}[mybox/.style={rectangle, draw, minimum size=10mm}]
  \matrix (A) [matrix of nodes, column sep=-\pgflinewidth,
    row 1/.style={nodes={mybox, anchor=center}},
    row 2/.style={font=\footnotesize, inner ysep=2mm}]
    {
        9 & 5 & 13 & 19 & 12 & 8 & 7 & 4 & 21 &  2 &  6 & 11\\
        1 & 2 &  3 &  4 &  5 & 6 & 7 & 8 &  9 & 10 & 11 & 12\\
        };
    \draw[ultra thick] (A-1-1.north west) rectangle (A-1-12.south east);
    \end{tikzpicture}
\end{center}

\end{document}

enter image description here

Update:

Column labels can be automatically defined:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{matrix}

\begin{document}

\begin{center}
  \begin{tikzpicture}[mybox/.style={rectangle, draw, minimum size=10mm}]
  \matrix (A) [matrix of nodes, column sep=-\pgflinewidth,
    row 1/.style={nodes={mybox, anchor=center}},
    row 2/.style={font=\footnotesize, inner ysep=2mm, 
           nodes={node contents=\the\pgfmatrixcurrentcolumn}},
    nodes in empty cells]
    {
        9 & 5 & 13 & 19 & 12 & 8 & 7 & 4 & 21 &  2 &  6 & 11\\
         &  &  &  &  &  &  &  &  &  &  & \\
        };
    \draw[ultra thick] (A-1-1.north west) rectangle (A-1-12.south east);
    \end{tikzpicture}
\end{center}

\end{document}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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