# Plot 3D stacked squares with shadow

This is an image I draw with tools. But I need to draw it with Tikz. And The 3 squares in the middle, I need to make them looks like 3D stacked with shadow. And the fonts on it, like 'a1', 'a2', ... will also be skewed. I don't know how to draw it, but I daw a sketch by pencil:

I hope that I can control the font size, the font is Helvetica. I am not familiar with Tikz, but it is powerful and amazing! I need to draw this graph. Anyone knows how to achieve the 3D image? Looking forward to your replies! Thanks very much!

• What about using PStricks? – Werner Jul 22 '14 at 13:57
• Hi @Werner , I never use PStricks. What I use is OmniGraffle. But I want to draw it with LaTeX code and manipulate characters such as shade, square color, font size and so on. – Excalibur Jul 22 '14 at 15:41
• Hi @Werner , do you know how to use PStricks to implement the effect? I misunderstood the PStricks as a software like PS. Thanks very much! – Excalibur Jul 22 '14 at 21:30

Borrowing from Bruno's definition of \slantbox at Shear transform a "box", I was able to construct the following, using simple stacks of \fcolorboxes. The perspective is completely determined by three parameters: \myrotate (the baseline rotation), \myslant (the slant magnitude or fallback parameter), and the short-stacking gap.

First, I demonstrate some variations on the perspective parameters:

\documentclass{article}
\usepackage{stackengine,xcolor,graphicx}
\newsavebox{\foobox}
\newcommand{\slantbox}[2][.5]{\mbox{%
\sbox{\foobox}{#2}%
\hskip\wd\foobox
\pdfsave
\pdfsetmatrix{1 0 #1 1}%
\llap{\usebox{\foobox}}%
\pdfrestore
}}
\def\mybox#1{\strut\makebox[\baselineskip]{$#1$}}
\def\mycell#1#2{\fcolorbox{black}{#1}{\mybox{#2}}}
\def\makeply#1#2#3{\expandafter\def\csname layer#1\endcsname{%
\stackunder[-\fboxrule]{%
\mycell{#3}{#2_1}\kern-\fboxrule\mycell{#3}{#2_3}}{%
\mycell{#3}{#2_2}\kern-\fboxrule\mycell{#3}{#2_4}}%
}%
}
\makeply{A}{a}{white}
\makeply{B}{b}{gray!30}
\makeply{C}{c}{gray!60}
\def\tristack{\Shortstack{\rotatebox{\myrotate}{\slantbox[\myslant]{\layerA}}
\rotatebox{\myrotate}{\slantbox[\myslant]{\layerB}}
\rotatebox{\myrotate}{\slantbox[\myslant]{\layerC}}}
}
\begin{document}
\def\myrotate{0}  \def\myslant{0}    \setstackgap{S}{1ex}  \tristack~~~
\def\myrotate{15} \def\myslant{-.9}  \setstackgap{S}{-5ex} \tristack~~~~~~
\def\myrotate{20} \def\myslant{-1.1} \setstackgap{S}{-7ex} \tristack
\end{document}


In fact, here is a general parametric variation of parameters (note that "Ply C atop stack" means that the stack was drawn as a \Shortunderstack, rather than as a \Shortstack):

And then, here, I try to recreate something like what the author is seeking:

\documentclass{article}
\usepackage{stackengine,xcolor,graphicx}
\newsavebox{\foobox}
\newcommand{\slantbox}[2][.5]{\mbox{%
\sbox{\foobox}{#2}%
\hskip\wd\foobox
\pdfsave
\pdfsetmatrix{1 0 #1 1}%
\llap{\usebox{\foobox}}%
\pdfrestore
}}
\def\mybox#1{\strut\makebox[\baselineskip]{$#1$}}
\def\mycell#1#2{\fcolorbox{black}{#1}{\mybox{#2}}}
\def\makeply#1#2#3{\expandafter\def\csname layer#1\endcsname{%
\stackunder[-\fboxrule]{%
\mycell{#3}{#2_1}\kern-\fboxrule\mycell{#3}{#2_3}}{%
\mycell{#3}{#2_2}\kern-\fboxrule\mycell{#3}{#2_4}}%
}%
}
\def\tristack{\Shortstack{\rotatebox{\myrotate}{\slantbox[\myslant]{\layerA}}
\rotatebox{\myrotate}{\slantbox[\myslant]{\layerB}}
\rotatebox{\myrotate}{\slantbox[\myslant]{\layerC}}}
}
\def\makestrip#1#2#3{\expandafter\def\csname strip#1\endcsname{%
\setstackgap{S}{-\fboxrule}\Shortstack{%
\mycell{#3}{#2_1} \mycell{#3}{#2_2} \mycell{#3}{#2_3} \mycell{#3}{#2_4}%
}\kern-\fboxrule}%
}
\def\tristrip{\stripA\stripB\stripC}
\def\makecomponents#1#2#3{\makeply{#1}{#2}{#3}\makestrip{#1}{#2}{#3}}
\makecomponents{A}{a}{white}
\makecomponents{B}{b}{gray!30}
\makecomponents{C}{c}{gray!60}
\begin{document}
\def\myrotate{0}  \def\myslant{0}    \setstackgap{S}{-.2\fboxsep}
\stackon[10pt]{$M_1$}{\tristack}\hspace{.1cm}
\raisebox{62pt}{\scalebox{2.5}{$\leftarrow$}}\hspace{.1cm}
\def\myrotate{15} \def\myslant{-.9}  \setstackgap{S}{-5ex}
\stackon[12pt]{$M$}{\tristack}\hspace{.7cm}
\raisebox{62pt}{\scalebox{2.5}{$\rightarrow$}}\hspace{.2cm}
\stackon[25pt]{$M_2$}{\tristrip}
\end{document}


• Wow! That is excellent! Thanks very much @Steven B. Segletes ! – Excalibur Jul 30 '14 at 5:07

I got a bit bored in the end but here is a TikZ implementation of the same mechanism Steven gives in his answer. With TikZ you can access the trafo matrix entries via <x,y>scale and <x,y>slant keys. Due to Helvetica, this needs Lua/XeLatex.

\documentclass{article}
\usepackage{tikz,amsmath,fontspec}
\setsansfont{Helvetica}
\usetikzlibrary{matrix}
% make a generic matrix style
\tikzset{mycell/.style={
execute at empty cell={\node[draw,font=\sffamily,minimum size=5mm,outer sep=0]{
#1$_{\text{\pgfmathparse{int(2*(\pgfmatrixcurrentrow-1)+\pgfmatrixcurrentcolumn)}\pgfmathresult}}$
};},row sep=-\pgflinewidth,column sep=-\pgflinewidth},ampersand replacement=\&,inner sep=0
}
\begin{document}
\begin{tikzpicture}
\foreach \x[count=\xi from 0,evaluate=\xs using 100-50*\xi] in{a,b,c}{
\matrix[mycell=\x,fill=gray!\xs] at (0,\xi) {\&\\\&\\};}

\begin{scope}[shift={(3cm,5mm)},transform canvas={xslant=-1},transform shape]
\foreach \x[count=\xi from 0,evaluate=\xs using 100-50*\xi] in{a,b,c}{
\matrix[mycell=\x,fill=gray!\xs] at (0.75*\xi,0.75*\xi) {\&\\\&\\};}
\end{scope}
\end{tikzpicture}
\end{document}


• Thanks very much @percusse ! Combine your solution with the previous one, both the font and image are perfect! – Excalibur Jul 30 '14 at 5:08

A pstricks version using the rich pst-3dplot package:

\documentclass{article}
\usepackage{pst-3dplot,xcolor,multido,graphicx}

\newcommand{\clap}[1]{\makebox[0pt]{#1}}
\newcommand{\preframelabel}{}
\begin{document}

\begin{pspicture}(\textwidth,12)
\psset{linewidth = .4pt, fillstyle = solid, unit = 0.5, Alpha = 30, Beta = 25, plane = xy}
\multido{\iBa=1+1,\iBb=12+-4}{3}{%
\expandafter\ifcase\iBa
\or   \renewcommand{\preframelabel}{a}\psset{fillcolor=white} % 1
\or   \renewcommand{\preframelabel}{b}\psset{fillcolor=black!10} % 2
\else \renewcommand{\preframelabel}{c}\psset{fillcolor=black!20}% 3
\fi%
\multido{\iC=1+2}{2}{%
\multido{\iR=\iBb+-2}{2}{%
\psframe(\iC,\iR)(\numexpr\iC-2\relax,\numexpr\iR+2\relax)%
}%
}%
}

\rput(5,8){\scalebox{3}{$\Leftarrow$}}

\rput(12,2){\psset{unit=0.7}
\multido{\iBa=3+-1,\iBb=9+4}{3}{%
\expandafter\ifcase\iBa
\or   \renewcommand{\preframelabel}{a}\psset{fillcolor=white} % 1
\or   \renewcommand{\preframelabel}{b}\psset{fillcolor=black!10} % 2
\else \renewcommand{\preframelabel}{c}\psset{fillcolor=black!20}% 3
\fi%
\multido{\iC=5+-4}{2}{%
\multido{\iR=1+4}{2}{%
\pstThreeDSquare(\iC,\iR,\iBb)(4,0,0)(0,4,0)%
\pstPlanePut(\number\numexpr\iC+2\relax,\number\numexpr\iR+2\relax,\iBb){%
\rotatebox{180}{%
\clap{%
\raisebox{-.5\height}{%
}%
}%
}}

\rput(16,8){\scalebox{3}{$\Rightarrow$}}

\multido{\iB=1+1,\iR=20+2}{3}{%
\expandafter\ifcase\iB
\or   \renewcommand{\preframelabel}{a}\psset{fillcolor=white} % 1
\or   \renewcommand{\preframelabel}{b}\psset{fillcolor=black!10} % 2
\else \renewcommand{\preframelabel}{c}\psset{fillcolor=black!20}% 3
\fi%
\multido{\iC=10+-2}{4}{%