Here I introduce \pushfigure[alignment]{width}{content}{captioningof}
to push figures onto a "stack", and then \popfigures
to set them all on a line. In all cases, captioning should be done with \captionof
for any figure being "pushed". Bottom alignment is the default.
The \pushfigure
phase of the operation saves all the parameters, and measures the height (plus any depth) of the content
. It saves the maximum height+depth of all the contents that have been pushed.
The \popfigures
phase performs a \stackinset
of the figure atop a rule of the maximum-content-height, using the saved alignment for the figure. This achieves proper vertical alignment of the figures. Any captioning that was specified is applied below the vertical \rule
, which will keep all captions at the same height, regardless of content alignment.
An \hfill
is inserted at the beginning and after each figure popped. All parameters (counters/lengths) are reset at the end of the "pop", to prepare for the next sequence of "push"es.
For this MWE, I reduced the value of \abovecaptionskip
to 6pt, which I find more visually pleasing when employing subfigures.
EDITED to demonstrate tabular
and \parbox
content. REEDITED to account for the fact that bottom aligned tabular
and \parbox
boxes can still have depth, associated with descending letters on the bottom line.
% arara: pdflatex
% !arara: indent: {overwrite: yes}
\documentclass{article}
\usepackage{graphicx}
\usepackage[showframe=true,textwidth=12cm]{geometry}
\usepackage{amsmath}
\usepackage{subcaption}
\usepackage{stackengine,ifthen}
\newcounter{figstack}
\newcounter{figindex}
\newlength\fight
\newcommand\pushfigure[4][b]{%
\stepcounter{figstack}%
\expandafter\def\csname %
figalign\romannumeral\value{figstack}\endcsname{#1}%
\expandafter\def\csname %
figwd\romannumeral\value{figstack}\endcsname{#2}%
\expandafter\def\csname %
figcontent\romannumeral\value{figstack}\endcsname{#3}%
\expandafter\def\csname %
figcap\romannumeral\value{figstack}\endcsname{#4}%
\setbox0=\hbox{%
\begin{minipage}{#2}#3\end{minipage}}%
\ifdim\dimexpr\ht0+\dp0\relax>\fight\global\setlength{\fight}{%
\dimexpr\ht0+\dp0\relax}\fi%
}
\newcommand\popfigures{%
\setcounter{figindex}{0}%
\hfill%
\whiledo{\value{figindex}<\value{figstack}}{%
\stepcounter{figindex}%
\def\tmp{\csname figwd\romannumeral\value{figindex}\endcsname}%
\begin{minipage}[t]{\tmp}%
\centering%
\stackinset{c}{}%
{\csname figalign\romannumeral\value{figindex}\endcsname}{}%
{\csname figcontent\romannumeral\value{figindex}\endcsname}%
{\rule{0pt}{\fight}}\par%
\csname figcap\romannumeral\value{figindex}\endcsname%
\end{minipage}%
\hfill%
}%
\setcounter{figstack}{0}%
\setlength{\fight}{0pt}%
\hfill%
}
\setlength\abovecaptionskip{6pt}
\begin{document}
\pushfigure{.1\textwidth}
{\includegraphics[width=\textwidth]{example-image-a}}%
{\captionof{figure}{}}
\pushfigure[t]{.15\textwidth}
{\includegraphics[width=\textwidth]{example-image-b}}%
{\captionof{figure}{}}
\pushfigure[t]{.2\textwidth}
{\includegraphics[width=\textwidth]{example-image-c}}%
{}
\pushfigure[c]{.1\textwidth}
{\includegraphics[width=\textwidth]{example-image}}%
{}
\pushfigure[c]{.2\textwidth}
{\includegraphics[width=\textwidth]{example-image}}%
{}
\noindent\popfigures
\begin{figure}[!htb]
\captionsetup{labelformat=parens}
\pushfigure[t]{.1\textwidth}
{\includegraphics[width=\textwidth]{example-image-a}}
{\captionof{subfigure}{}}
\pushfigure{.15\textwidth}
% {\includegraphics[width=\textwidth]{example-image-b}}
{\begin{tabular}[b]{ccc}a&b&c\\dd&e&fff\\%
a&b&c\\x&yy& z\end{tabular}}
{\captionof{subfigure}{}}
\popfigures\par
\captionsetup{labelformat=default}
\caption{}
\end{figure}
\begin{figure}[!htb]
\captionsetup{labelformat=parens}
\pushfigure[c]{.1\textwidth}
{\includegraphics[width=\textwidth]{example-image-a}}
{\captionof{subfigure}{}}
\pushfigure[c]{.15\textwidth}
% {\includegraphics[width=\textwidth]{example-image-b}}
{\parbox{\textwidth}{%
This is text and a bit more text and some more text}}
{\captionof{subfigure}{}}
\popfigures\par
\captionsetup{labelformat=default}
\caption{}
\end{figure}
\end{document}
VERSION FOR TABLES
Directly analogous to figure version, but with \poptables
(sub)captions placed above the figures. Note, though, that if table captions are multiline, the captions will be bottom-aligned with respect to other captions in the same row.
% arara: pdflatex
% !arara: indent: {overwrite: yes}
\documentclass{article}
\usepackage{graphicx}
\usepackage[showframe=true,textwidth=12cm]{geometry}
\usepackage{amsmath}
\usepackage{subcaption}
\usepackage{stackengine,ifthen}
\newcounter{tblstack}
\newcounter{tblindex}
\newlength\tblht
\newcommand\pushtable[4][b]{%
\stepcounter{tblstack}%
\expandafter\def\csname %
tblalign\romannumeral\value{tblstack}\endcsname{#1}%
\expandafter\def\csname %
tblwd\romannumeral\value{tblstack}\endcsname{#2}%
\expandafter\def\csname %
tblcontent\romannumeral\value{tblstack}\endcsname{#3}%
\expandafter\def\csname %
tblcap\romannumeral\value{tblstack}\endcsname{#4}%
\setbox0=\hbox{%
\begin{minipage}{#2}#3\end{minipage}}%
\ifdim\dimexpr\ht0+\dp0\relax>\tblht\global\setlength{\tblht}{%
\dimexpr\ht0+\dp0\relax}\fi%
}
\newcommand\poptables{%
\setcounter{tblindex}{0}%
\hfill%
\whiledo{\value{tblindex}<\value{tblstack}}{%
\stepcounter{tblindex}%
\def\tmp{\csname tblwd\romannumeral\value{tblindex}\endcsname}%
\begin{minipage}[b]{\tmp}%
\centering%
\csname tblcap\romannumeral\value{tblindex}\endcsname\par%
\stackinset{c}{}%
{\csname tblalign\romannumeral\value{tblindex}\endcsname}{}%
{\csname tblcontent\romannumeral\value{tblindex}\endcsname}%
{\rule{0pt}{\tblht}}%
\end{minipage}%
\hfill%
}%
\setcounter{tblstack}{0}%
\setlength{\tblht}{0pt}%
\hfill%
}
\setlength\abovecaptionskip{6pt}
\begin{document}
\pushtable{.1\textwidth}
{\includegraphics[width=\textwidth]{example-image-a}}%
{\captionof{table}{}}
\pushtable[t]{.15\textwidth}
{\includegraphics[width=\textwidth]{example-image-b}}%
{\captionof{table}{}}
\pushtable[t]{.2\textwidth}
{\includegraphics[width=\textwidth]{example-image-c}}%
{}
\pushtable[c]{.1\textwidth}
{\includegraphics[width=\textwidth]{example-image}}%
{}
\pushtable[c]{.2\textwidth}
{\includegraphics[width=\textwidth]{example-image}}%
{}
\noindent\poptables
\bigskip\begin{table}[!htb]
\captionsetup{labelformat=default}
\caption{}
\captionsetup{labelformat=parens}
\pushtable[t]{.1\textwidth}
{\includegraphics[width=\textwidth]{example-image-a}}
{\captionof{subtable}{}}
\pushtable{.15\textwidth}
% {\includegraphics[width=\textwidth]{example-image-b}}
{\begin{tabular}[b]{ccc}a&b&c\\dd&e&fff\\%
a&b&c\\x&yy& z\end{tabular}}
{\captionof{subtable}{}}
\poptables\par
\end{table}
\begin{table}[!htb]
\captionsetup{labelformat=default}
\caption{}
\captionsetup{labelformat=parens}
\pushtable[c]{.1\textwidth}
{\includegraphics[width=\textwidth]{example-image-a}}
{\captionof{subtable}{}}
\pushtable[c]{.15\textwidth}
% {\includegraphics[width=\textwidth]{example-image-b}}
{\parbox{\textwidth}{%
This is text and a bit more text and some more text}}
{\captionof{subtable}{}}
\poptables\par
\end{table}
\end{document}
Now the tricky part is if one wants table and figures on the same row. The macro \popfigures
achieves its vertical alignment by using top-aligned minipages. The \poptables
does it by using bottom-aligned minipages. Neither of these approaches will work if a row must accommodate both top and bottom captioning.
That problem has not yet been solved.
Best Answer
You have to leave a blank line before
\vspace{3mm}
, not after it. On the other hand, you can also use only onetabular
and add the vertical space with\\[3mm]
.