The goal
My goal is to align side-by-side figure
s, table
s, and text in minipages according to the top, middle and bottom of the largest such minipage
. This makes it different (I believe) from the related links and references at the bottom, which detail the baseline of the surrounding text. I don't know which figure is largest.
For example, consider the following figure:
Notice that A
and C
are aligned to the bottom of C
and that the fourth image is aligned to the middle of C
, the largest image.
The algorithm for this is quite straightforward:
- put all of the
minipage
environments in a box, and measure the height - then set each
minipage
using\begin{minipage}[b][MAX HEIGHT][<alignment>]
so that each one is 'anchored' to the bottom, each one has the same height (cruicial), and then the position of each contents can be specified (t
,c
, orb
).
The problem
The problem I'm having is when I try to caption
these objects, the numbering falls down. I get, for example, the following:
Having read Is there a switch to turn off LaTeX counters from inside a box?, I thought I could fix it with \savecounters@
and restorecounters@
.
The question
How can I modify my code so that the numbering of both figure
s and subfigure
s is as expected? Solutions would hopefully scale naturally to tables.
I'm very open to alternatives that accomplish the same idea; I have tried with the adjustbox
package, for example, but no luck so far.
The MWE
% arara: pdflatex
% !arara: indent: {overwrite: yes}
\documentclass{article}
\usepackage{graphicx}
\usepackage[showframe=true,textwidth=12cm]{geometry}
\usepackage{amsmath}
\usepackage{subcaption}
\usepackage{environ}
\newsavebox{\vabox}
\makeatletter
\NewEnviron{verticallyaligned}{%
% temporarily set \vamaxheight to nothing during the measurements
\let\vamaxheight\relax
% temporarily disable figure numbering
\savecounters@
% measure the height of the body
\begin{lrbox}{\vabox}
\BODY%
\end{lrbox}%
% turn figure numbering back on
\restorecounters@
% set the height of the minipage box
\newlength{\vamaxheight}
\setlength{\vamaxheight}{\ht\vabox}
% output the body, which now contains the new height :)
\noindent\makebox[\linewidth][c]{\mbox{}\hfill\BODY\hfill\mbox{}}%
}
\begin{document}
\begin{verticallyaligned}
\noindent
\begin{minipage}[b][\vamaxheight][b]{.10\textwidth}
\centering
\includegraphics[width=\textwidth]{example-image-a}
\captionof{figure}{}
\end{minipage}%
\hfill
\begin{minipage}[b][\vamaxheight][t]{.15\textwidth}
\centering
\includegraphics[width=\textwidth]{example-image-b}
\captionof{figure}{}
\end{minipage}%
\hfill
\begin{minipage}[b][\vamaxheight][t]{.20\textwidth}
\centering
\includegraphics[width=\textwidth]{example-image-c}
\end{minipage}%
\hfill
\begin{minipage}[b][\vamaxheight][c]{.10\textwidth}
\centering
\includegraphics[width=\textwidth]{example-image}
\end{minipage}%
\hfill
\begin{minipage}[b][\vamaxheight][t]{.20\textwidth}
\centering
\includegraphics[width=\textwidth]{example-image}
\end{minipage}%
\end{verticallyaligned}
\begin{figure}[!htb]
\begin{verticallyaligned}
\begin{subfigure}[b][\vamaxheight][t]{.10\textwidth}
\centering
\includegraphics[width=\textwidth]{example-image-a}
\caption{}
\end{subfigure}%
\hfill
\begin{subfigure}[b][\vamaxheight][t]{.15\textwidth}
\centering
\includegraphics[width=\textwidth]{example-image-b}
\caption{}
\end{subfigure}%
\end{verticallyaligned}
\caption{}
\end{figure}
\begin{figure}[!htb]
\begin{verticallyaligned}
\begin{subfigure}[b][\vamaxheight][c]{.10\textwidth}
\centering
\includegraphics[width=\textwidth]{example-image-a}
\caption{}
\end{subfigure}%
\hfill
\begin{subfigure}[b][\vamaxheight][c]{.15\textwidth}
\centering
\includegraphics[width=\textwidth]{example-image-b}
\caption{}
\end{subfigure}%
\end{verticallyaligned}
\caption{}
\end{figure}
\end{document}
Best Answer
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 thecontent
. 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 alignedtabular
and\parbox
boxes can still have depth, associated with descending letters on the bottom line.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.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.