# How to draw stacked rectangles (in a third dimension), but with the intersected lines clipped + grid pattern for each rectangle + shaded fill + text

As the title indicates, I'm trying to draw a figure (see enclosed example) which comprises of different rectangles that are stacked (after each other) in the third dimension. I tried different things (incl. using preaction-mode & clipping-feature) but the result was always very disappointing. I ended up with a messy-looking manual result, which I'm in no way comfortable with ... This is the MWE:

\documentclass[a4paper,11pt]{article} \usepackage{tikz}

\begin{document}

\begin{tikzpicture}

\draw [step=0.2,thin,gray!40] (0,0) grid (3,2);
\draw  [line width=0.5mm] (0,0) rectangle (3,2);
\draw  [xshift=10pt,yshift=8pt,line width=0.5mm,black] (0,2) -- (3,2);
\draw  [xshift=10pt,yshift=8pt,line width=0.5mm,black] (3,0) -- (3,2);
\draw  [xshift=10pt,yshift=8pt,line width=0.5mm,black] (0,1.74) -- (0,2);
\draw  [xshift=10pt,yshift=8pt,line width=0.5mm,black] (3,0) -- (2.65,0);
\draw [xshift=10pt,yshift=0.9pt,step=0.2,thin,gray!40] (0,2) grid (3,2.2);
\draw [xshift=25pt,yshift=11.2pt,step=0.2,thin,gray!40] (2,0) grid (2.4,1.6);
\draw [->, line width=0.3mm] (2,2.5) -- (3.5,4.1);
\draw  [xshift=60pt,yshift=90pt,line width=0.5mm] (0,0) rectangle (3,2);
\draw [xshift=60pt,yshift=90pt,step=0.2,thin,gray!40] (0,0) grid (3,2);

\end{tikzpicture}

\end{document}


which leads to

This created image gives a first rough idea in which direction it should go, but as one can see ... there is still room for improvement.

Now my question(s):

Is there a simple, straightforward, flexible method to achieve a better result than this?

Is it possible to have the light grid lines & shaded fill inside all the rectangles?

I want also to add text to the figure ... specifically:

• along the arrow with the text "dimension z"
• "beautifully placed" text along the width & height of the front rectangle
• symbol or letter inside one of the girdboxes

## 2 Answers

You can use pics or nodes or foreached rectangles etc. once you get the drawing order right. Here is a pic example (without the extras):

\documentclass[tikz]{standalone}
\begin{document}
\begin{tikzpicture}[
squared notebook/.pic={\clip[postaction={shade,left color=gray}](0,0) rectangle (4,2);
\draw[gray!40,thin] (0,0) grid[step=0.2] (4,2);
\draw[ultra thick](0,0) rectangle (4,2);}
]
\foreach \x in {2,0.5,0}\pic at (\x,\x){squared notebook};
\draw[-latex] (4.5,0) -- +(1.5,1.5) node[below right,midway] {$z$};
\node[rotate=90] (h) at (-.5,1) {beautifully};
\node (w) at (2,-0.5) {placed};
\end{tikzpicture}
\end{document}


• Nice compact piece of code. Is there a way to incorporate those "extra's" (i.e. arrow, text + shading) herein? – WaffleTeX Jun 29 '15 at 13:05
• @WaffleTeX Yes. See the edit. – percusse Jun 29 '15 at 14:06
• Nice, one last question concerning the gradient fill. Is it somehow possible to have a gradient over the z-direction with your approach? Specifically: that the front rectangle has a certain solid color and that it fades away over z, but slightly visible in the last rectangle? I tried to define a shading path, but that was apparently a no-go... – WaffleTeX Jun 29 '15 at 15:57

You could also define a macro that draws the rectangles.

The optional argument here (#1) allows you to specify additional styling for the node. The first mandatory argument (#2) defines the name for the node, which you can refer to later, e.g. to add labels to the sides of the frontmost rectangle. The second mandatory argument defines the position of the rectangle. They are all drawn with the lower left corner in (0,0), and then moved to the coordinate defined by #3, through the shift argument to the scope environment. When you do \gridbox{<first arg>}{<second arg>}, the second argument has to be a two numbers separated by a comma. For example, with \gridbox{A}{2,1}, the lower left corner of the box is in the coordinate (2,1).

To shade a grid, you can use the optional argument, for example

\gridbox[shade,left color=blue!50,right color=white]{Z}{0,0}


Or if all the grids should have the same shading, just replace fill=white in the definition with the appropriate shading keys.

\documentclass[border=3mm]{standalone}
\usepackage{tikz}
\newcommand\gridbox[3][]{%
\begin{scope}[shift={(#3)}]
\node [minimum width=3cm,minimum height=2cm,anchor=south east,fill=white,#1] (#2) at (0,0) {};
\draw [step=0.2cm,thin,gray!40] (#2.south west) grid (#2.north east);
\draw [ultra thick] (#2.south west) rectangle (#2.north east);
\end{scope}
}
\begin{document}
\begin{tikzpicture}

\gridbox{X}{1.8,3}
\gridbox{Y}{0.3,0.3}
\gridbox[shade,left color=blue!50,right color=white]{Z}{0,0}

\node [below] at (Z.south) {Foo};
\node [rotate=90,above] at (Z.west) {Bar};

\draw [shorten >=0.2cm,shorten <=0.2cm,-latex] (Y.north) --node[sloped,above]{Baz} (X.center);

\end{tikzpicture}
\end{document}

• @ Torbjorn T. -- I like your answer too. It solves almost everything. However, can you briefly explain what this line do --> \begin{scope}[shift={(#3)}] <-- ? I know that "scope" is a feature that allows to define local coordinates (if I'm not mistaken...), but what about shift=#3? I assume that in order to have a gradient-effect, I should adapt the option "fill=white", right? – WaffleTeX Jun 29 '15 at 13:33
• @WaffleTeX I edited my answer a bit. Yes, you can modify fill=white, or probably you can use the optional argument to gridbox. I can add an example later. – Torbjørn T. Jun 29 '15 at 14:05