Optimal subfigure width to span \textwidth
What is happening is that between each subfigure you have a new line that, for TeX, is exactly the same thing as a space. So what you have is three subfigures with two spaces in between. To fix it, add a %
after each subfigure so that TeX will not consider it as a space:
\documentclass{article}
\usepackage{graphicx}
\usepackage{subcaption}
\begin{document}
\begin{figure}
\centering
\begin{subfigure}[t]{0.33\textwidth}
\centering% < useless
\includegraphics[width=\textwidth]{example-image-a}
\caption{a}
\end{subfigure}% < HERE
\begin{subfigure}[t]{0.33\textwidth}
\centering% < useless
\includegraphics[width=\textwidth]{example-image-b}
\caption{b}
\end{subfigure}% < AND HERE
\begin{subfigure}[t]{0.33\textwidth}
\centering% < useless
\includegraphics[width=\textwidth]{example-image-c}
\caption{c}
\end{subfigure}
\end{figure}
\end{document}
Edit:
Since my answer was chosen even with all the other answers down here, I felt the need to add a few explanations for the future generations ;)
Why 3 * 0.33\textwidth
does not fit in \textwidth
?
Firstly, as I said above, the major problem was that when TeX reads either a space
or a new line
character, it understands both as a space
. The rule is different for multiple space
s or new lines
. Multiple space
s are treated by TeX as a single space
and multiple new line
s are treated by TeX as a paragraph ending. For example, if you compile this:
\documentclass{article}
\usepackage[paperwidth=4in]{geometry}
\begin{document}
This is written
on several
separate lines
separated by
a new line
character or
by spaces.
But when processed by \TeX, the result is two normal paragraphs!
\end{document}
you get this:
This is quite obvious when writing only text, like in the example above. But the same applies when you are using figures. If you insert a new line
between consecutive \includegraphics
or subfigure
environments, TeX will treat them as spaces!
In Viesturs' MWE, the subfigure environments are separated by new line
s, which are treated by TeX as spaces.
To check the effect of the spaces in Viesturs' MWE, we can first measure the size of \textwidth
with:
textwidth: \the\textwidth
and we get , thus the width of the subfigures is 0.33\textwidth
, which is exactly 113.85pt
.
Furthermore, we can measure the space of the current font using:
space: \the\fontdimen2\font\space plus \the\fontdimen3\font\space minus \the\fontdimen4\font
and we get . For TeX, this means that the space is 3.333pt
wide, but can be stretched by 1.666pt
or shrinked by 1.111pt
.
So, assuming that TeX will shrink the space as far as it can to try to fit the three subfigure
s in a single line, the layout would have three figures of 113.85pt
, and two spaces of 3.333pt minus 1.111pt
(= 2.222pt
). So the with of the contents is 3 * 113.85pt + 2 * 2.222pt = 345.994pt
, Which is 0.994pt
larger than the available \textwidth
. Thus TeX will give up on putting it in one line and break the line before inserting the third subfigure!
But Phelype, how do I fix this?!?!
Well, Jimmy, another couple of things about TeX is that:
After TeX sees a
%
sign, it ignores everything that comes after it on the current line. This is why commenting works this way in TeX (and most programming languages, actually). But for the problem we're facing now, this is why the%
sign makes TeX ignore thenew line
character between eachsubfigure
.TeX ignores leading
space
s! So the indentation before the following\begin{subfigure}
is also ignored!
So, as far as TeX is concerned, this:
\end{subfigure}% < HERE
\begin{subfigure}[t]{0.33\textwidth}
is exactly the same as this:
\end{subfigure}\begin{subfigure}[t]{0.33\textwidth}
% ^ No spaces!!!
and observe that the second one does not have any space
between the subfigure
s. Now, if we do the previous calculation without the spaces, we have 3 * 113.85pt = 341.55pt
, which fits in the current \textwidth
!
This may seem obvious to some, but for starters it's tricky to promptly see why 3 * 0.33\textwidth
does not fit in \textwidth
. A few months ago I frequently found myself naively changing 0.33\textwidth
to 0.329\textwidth
to make the figures fit on one line :P
Disclaimer: All the above is valid in normal typesetting mode. In verbatim, math, or other special environments the rules are different!
How to optimally chose
subfigure
widths so that the figure spans\textwidth
exactly, for N = 2, 3, 4, ...subfigure
environments?
First off, note that all four
\centering
directives in your code may (and, in fact, should!) be omitted.Second, assuming you wish to leave a bit of whitespace between adjacent images, you should change the relative widths for three side-by-side subfigures from
0.33\textwidth
to something like0.3\textwidth
or0.31\textwidth
. Similarly, use0.23\textwidth
or0.24\textwidth
for four side-by-side subfigures, and0.48\textwidth
for two side-by-side subfigures.Finally, use
\hfill
directives to maximize the separation between the subfigures placed on a line.
\documentclass{article}
\usepackage{graphicx,subcaption}
\begin{document}
\begin{figure}
\begin{subfigure}[t]{0.31\textwidth}
\includegraphics[width=\textwidth]{example-image-a}
\caption{a}
\end{subfigure}\hfill% % <-- \hfill is new
\begin{subfigure}[t]{0.31\textwidth}
\includegraphics[width=\textwidth]{example-image-b}
\caption{b}
\end{subfigure}\hfill% % <-- \hfill is new
\begin{subfigure}[t]{0.31\textwidth}
\includegraphics[width=\textwidth]{example-image-c}
\caption{c}
\end{subfigure}
\bigskip\bigskip
\begin{subfigure}[t]{0.23\textwidth}
\includegraphics[width=\textwidth]{example-image-a}
\caption{dd}
\end{subfigure}\hfill%
\begin{subfigure}[t]{0.23\textwidth}
\includegraphics[width=\textwidth]{example-image-b}
\caption{ee}
\end{subfigure}\hfill%
\begin{subfigure}[t]{0.23\textwidth}
\includegraphics[width=\textwidth]{example-image-c}
\caption{f\kern0ptf}
\end{subfigure}\hfill%
\begin{subfigure}[t]{0.23\textwidth}
\includegraphics[width=\textwidth]{example-image-a}
\caption{gg}
\end{subfigure}
\caption{Seven subfigures}
\end{figure}
\end{document}
The following uses tabularx
to automate the process of specifying the number of elements to distribute evenly across \textwidth
:
\documentclass{article}
\usepackage{graphicx,subcaption,tabularx}
\newenvironment{distsubfig}[1]
{\noindent\tabularx{\textwidth}{@{} *{#1}{X} @{}}}
{\endtabularx\par}
\begin{document}
\begin{figure}
\begin{distsubfig}{3}
\includegraphics[width=\linewidth]{example-image-a}
\caption{a}
&
\includegraphics[width=\linewidth]{example-image-b}
\caption{b}
&
\includegraphics[width=\linewidth]{example-image-c}
\caption{c}
\end{distsubfig}
\bigskip
\begin{distsubfig}{5}
\includegraphics[width=\linewidth]{example-image-a}
\subcaption{a}
&
\includegraphics[width=\linewidth]{example-image-b}
\subcaption{b}
&
\includegraphics[width=\linewidth]{example-image-c}
\subcaption{c}
&
\includegraphics[width=\linewidth]{example-image-a}
\subcaption{e}
&
\includegraphics[width=\linewidth]{example-image-b}
\subcaption{f}
\end{distsubfig}
\begin{distsubfig}{4}
\includegraphics[width=\linewidth]{example-image-c}
\subcaption{g}
&
\includegraphics[width=\linewidth]{example-image-a}
\subcaption{h}
&
\includegraphics[width=\linewidth]{example-image-b}
\subcaption{i}
&
\includegraphics[width=\linewidth]{example-image-c}
\subcaption{j}
\end{distsubfig}
\caption{A figure caption}
\end{figure}
\end{document}
The distsubfig
environment takes a single argument: the number of subfloats to distribute evenly across \textwidth
; alternatively, the number of X
-columns to use in a tabularx
. The gap between the subfloats are \tabcolsep
, just like in any tabular
environment (and can be changed).