8

I would like to create a graphic representing a stack of rectangles. I would ideally like a simple command like \stack{5} to create a stack of 5.

I can use the following code:

\draw[fill=blue] (0.4,-0.4) rectangle +(3,2);
\draw[fill=blue] (0.3,-0.3) rectangle +(3,2);
\draw[fill=blue] (0.2,-0.2) rectangle +(3,2);
\draw[fill=blue] (0.1,-0.1) rectangle +(3,2);
\draw[fill=blue] (0.0,-0.0) rectangle +(3,2);

enter image description here

However, it seems hard to turn that into a command, and if we need to shift the stack around it is a hassle to change all of the coordinates. I was thinking this might be better:

\draw[fill=blue] (0.4,-0.4)
  rectangle +(3,2) ++(-0.1,0.1)
  rectangle +(3,2) ++(-0.1,0.1)
  rectangle +(3,2) ++(-0.1,0.1)
  rectangle +(3,2) ++(-0.1,0.1)
  rectangle +(3,2) ++(-0.1,0.1);

enter image description here

This has the advantage that shifting it around only changes the coordinates in one obvious place, and it is even a little more clear about what is intended.

Unfortunately, this second version fills all the rectangles first, and then draws their outlines, so the "top" rectangle does not cover the rest of the stack.

Is there a simple way to draw overlapping regions using relative draw commands?

3
  • Scope the first one and shift that scope to move around.
    – percusse
    Aug 24 '12 at 9:40
  • No problem. I strongly recommend that you always include them. (Accidental rap rhyme :P)
    – percusse
    Aug 24 '12 at 9:51
  • Creating stacked shapes for tikzstyle with provides other solutions to draw stacked rectangles
    – Ignasi
    Aug 27 '12 at 10:10
6

Here's a solution that exploits the fact that paths constructed using the edge command are separate and thus are drawn separately. An edge path is as flexible as a to path so can be adapted to draw just about anything, including a rectangle. So we define a new to path and an edge style that invokes. it.

\documentclass{article}
%\url{http://tex.stackexchange.com/q/68555/86}
\usepackage{tikz}

\tikzset{
  edge rectangle/.style={
    to path={ rectangle (\tikztotarget)}
  }
}

\begin{document}
\begin{tikzpicture}
\draw[every edge/.append style={edge rectangle,fill=blue}] (0.4,-0.4)
  edge +(3,2) ++(-0.1,0.1)
  edge +(3,2) ++(-0.1,0.1)
  edge +(3,2) ++(-0.1,0.1)
  edge +(3,2) ++(-0.1,0.1)
  edge +(3,2) ++(-0.1,0.1);
\end{tikzpicture}
\end{document}

This results in the following:

stacked rectangles via edge commands

1
  • Thanks this is more what I was looking for! At first the idea of an edge drawing a rectangle seems a bit odd, but now seems pretty natural. This lets me use relative drawing commands, so I can position labels and other decorations based on one initial coordinate. Aug 24 '12 at 10:48
7

You can simply package everything up in to a command.

\documentclass{article}

\usepackage{tikz}

\newcommand{\stack}[3][5]{  
\foreach \x in {1,...,#1}
 { \draw[fill=blue] (\x/10,-\x/10) rectangle +(#2,#3); }
}

\begin{document}
\thispagestyle{empty}
\begin{tikzpicture}
  \stack{3}{2};
  \stack[2]{-2}{3};
\end{tikzpicture}
\end{document}

Sample output

3
  • Is there a typo, #3 is never used? Aug 24 '12 at 9:53
  • At a guess, the coordinates should be (#2,#3). Aug 24 '12 at 10:32
  • @JackSchmidt Andrew Stacey is right. Code corrected now and picture updatede. Aug 24 '12 at 10:51
4

Here is a simple solution based on Andrew Swann's answer:

rendered version of the tex

\documentclass{article}
\usepackage{tikz}
% \stack{5}{(4,0)}{(3,2)}{Label} draws a stack of 5 at (4,0) with dimensions (3,2)
% and labels the center with "Label"
\newcommand{\stack}[4]{
  \foreach \i in {1,...,#1} {
    \draw[fill=blue!50] #2 ++({0.1*(#1)},{-0.1*(#1)}) ++({-0.1*\i},{0.1*\i}) rectangle +#3;
  }
  \path #2 -- +#3 node[pos=0.5] {#4};
}
\begin{document}
\begin{tikzpicture}
\stack{5}{(0,0)}{(3,2)}{I}
\stack{3}{(4,0)}{(3,2)}{II}
\stack{1}{(8,0)}{(3,2)}{III}
\end{tikzpicture}
\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.