3

I need a figure like this (four vertically stacked rectangles with text; the two numbers in the texts are different and don't follow a pattern):

What I did:

%working
\documentclass{standalone}
\usepackage{tikz,amsmath}

\newcommand{\vrect}[2]{ %%% Need to pass an array of 4 arguments \foreach \pos [count=\i] in {{(0,-4)},{(0,-3)},{(0,-2)},{(0,-1)}}{ \node[draw=black,thick,minimum size=1cm] (z\i) at \pos {Val#1#2}; } } \begin{document} \begin{tikzpicture}[scale=1] %%\vrect{{1,1}, {3,5}, {8,7}, {1,0}}} %% How to use this? \vrect{1}{1} \end{tikzpicture}
\end{document}

I don't really know

  • how to pass an array as an argument
  • how to access arguments based on the index (tried #\i with failure)

Any help is appreciated. P.S. I need to draw few figures like this, so I created a \newcommand.

hola
  • 4,026
  • 3
  • 35
  • 72

3 Answers3

8

The \foreach command can iterate over multiple parameters, separated by /. You can use the array of the loop as parameter for your command. The position can be set with the counter \i by (0,-\i).

Note: You can pass an arbitrary number of parameters inside the array (don't have to be 4).

\documentclass{standalone}
\usepackage{tikz,amsmath}

\newcommand{\vrect}[1]{
    \foreach \x/\y [count=\i] in #1 {
        \node[draw=black,thick,minimum size=1cm] (z\i) at (0,-\i) {Val\x\y};
    }
}

\begin{document}
    \begin{tikzpicture}[scale=1]
        \vrect{{1/1, 3/5, 8/7, 1/0}}
    \end{tikzpicture}
\end{document}

enter image description here

dexteritas
  • 9,161
4

You can give your array as a single argument to \vect, however, it will be easier if instead of using the list {1,1}, {3,5}, {8,7}, {1,0} you instead use 1/1, 3/5, 8/7, 1/0. This way you can loop over your coordinates in the "normal" tikz fashion.

Here's your full (corrected) MWE:

\documentclass{standalone}
\usepackage{tikz,amsmath}

\newcommand{\vrect}[1]{ %%% Need to pass 4 arguments
    \foreach \x/\y [count=\i] in {#1} {
        \node[draw=black,thick,minimum size=1cm] (z\i) at (\x,\y) {Val\x-\y};
    }
}
\begin{document}
    \begin{tikzpicture}[scale=1]
      \vrect{1/1, 3/5, 8/7, 1/0} %% How to use this!
    \end{tikzpicture}
\end{document}

which produces

enter image description here

Notice that this will work for any number of arguments in the array.

EDIT

If you want the boxes stacked vertically this is marginally easier:

\documentclass{standalone}
\usepackage{tikz,amsmath}

\newcommand{\vrect}[1]{ %%% Need to pass 4 arguments
\foreach \x/\y [count=\i] in {#1} {
        \node[draw=black,thick,minimum size=1cm] (z\i) at (0,-\i) {Val\x-\y};
    }
}
\begin{document}
    \begin{tikzpicture}[scale=1]
      \vrect{1/1, 3/5, 8/7, 1/0} %% How to use this?
    \end{tikzpicture}
\end{document}

which produces:

enter image description here

Again, this will accept an arbitrary number of arguments.

4

If you're not tied to that weird syntax:

\documentclass{standalone}
\usepackage{tikz,amsmath}

\newcommand{\vrect}[1]{%
  \def\myarray{{#1}}%
  \foreach \pos [count=\i from 0] in {{(0,-4)},{(0,-3)},{(0,-2)},{(0,-1)}}{
    \pgfmathsetmacro{\val}{\myarray[\i]}%
    \node[draw=black,thick,minimum size=1cm] (z\i) at \pos {Val\val};
  }%
}
\begin{document}

\begin{tikzpicture}
\vrect{11,35,87,10}
\end{tikzpicture}

\end{document}

enter image description here

egreg
  • 1,121,712