Captions & subfigures

Every figure is numbered correctly and yet \ref prints a different number — the most frequently reported “wrong figure number” in LaTeX almost always comes from writing \label before \caption. There is no error and no warning; only the printed digit quietly lies. The caption command looks like a modest label, but numbering, cross-referencing and the list of figures are all decided here. This page covers why \caption works only inside a float, where \label must go, styling with the caption package, \captionof for things that are not floats, and subfigures labelled (a) and (b).

Why \caption only works inside a float

\caption{…} attaches explanatory text to a figure or table, but it only works inside figure or table. Write it in ordinary text and you are stopped by ! LaTeX Error: \caption outside float. The reason is that the command is not merely setting type: it looks at which kind of float it is inside and steps the matching counter. Inside figure it advances the figure counter, inside table the table counter. Outside a float that information does not exist, so there is no number to assign. Which is also why you never write the number yourself — and must not.

latex
\begin{figure}
  \centering
  \includegraphics[width=0.6\textwidth]{plot}
  \caption{Measured values against the theoretical curve}
  \label{fig:plot}   % after \caption -- always
\end{figure}

A word on convention: a figure's caption normally goes below the figure, a table's caption above the table. A table is read from the top down, so it is natural to announce what it contains before it starts. LaTeX sets \caption exactly where you write it, so put it before the artwork for a caption on top and after it for one below; the format itself — the gap between number and text, and so on — does not change with position. That said, the venue usually decides this, so check the style guide of the journal first.

What happens when \label comes before \caption

\label must always come after \caption. All \label does is record “the current number”, and the command that updates the current number to the figure's number is \caption. Put \label first and it records whatever counter moved last — normally the section number. Compile a figure inside Section 5 that should be numbered 2, with its \label before the \caption, and the auxiliary file receives \newlabel{fig:before}{{5}{1}...} and the text prints “Figure 5”. No error, no warning. Unless you read the output with your own eyes, the mistake survives to the final draft.

The trap has a shape. It feels natural to write \label right after \includegraphics, as though you were tagging the picture. But what \label refers to is not the picture; it is a counter, and the command that sets that counter is \caption. The remedy is simple: always keep \caption and \label on two adjacent lines. With nothing between them there is no room to get the order wrong. The same applies inside subfigures — a \label in a subfigure goes after that subfigure's own \caption. The general machinery of \label and \ref is covered on the cross-references page.

Short headings and the list of figures: \caption[...]{...}, \caption*, \ContinuedFloat

When a caption is long and only one line belongs in the list of figures, the optional argument is what you want: \caption[short heading]{long text}. What is in the brackets goes to \listoffigures; what is in the braces is set beside the figure. Omit the brackets and the full text flows into the list too, which wrecks the list as soon as several figures carry three-line captions. In a test document, \caption[Short entry for the list]{A long caption that is only shown under the figure} records only the short form in the .lof file. When the caption contains mathematics or a \cite, keeping the bracketed version plain also spares you typesetting accidents in the list.

Loading the caption package brings two variants into reach. \caption*{…} produces a caption that is neither numbered nor listed — right for a frontispiece or a chapter-opening plate. \ContinuedFloat makes a float carry the number of the float before it, which is what you need when a large figure has to be split across several floats. Put \ContinuedFloat at the head of a \begin{figure} and then \caption{Continued}, and what prints is a second sheet still numbered “Figure 1”. It is the standard move for a large survey figure that spans several pages without inflating the numbering.

latex
% short entry for the list, full text under the figure
\caption[Measured values and the model]{Measured values (dots) against the
  theoretical curve (solid). Error bars are one standard deviation.}

% no number, no entry in the list of figures
\caption*{Frontispiece}

% second sheet of a split figure keeps the previous number
\begin{figure}
  \ContinuedFloat
  \centering\includegraphics[width=\linewidth]{survey-part2}
  \caption{Continued}
\end{figure}

Styling captions with the caption package: \captionsetup

To change the font, the separator between number and text, or the alignment, use the caption package. Its author is Axel Sommerfeldt, its copyright notice reaches back to 1994, and the version in TeX Live 2024 is v3.6o of August 2023 — a tool kept in one pair of hands for three decades. Load it with \usepackage{caption} and configure it with \captionsetup{key=value, …}. The essential point about that command is scope: written in the preamble it governs the whole document, written inside a float it governs that one caption only.

KeyCommon valuesEffect
formatplain / hangHow the body is set; hang indents continuation lines by the label width
labelsepcolon / period / space / quad / newlineSeparator between label and text; the default is colon
fontsmall / footnotesize / it …Font and size of the caption as a whole
labelfontbf / sc / it …Font of the “Figure 1” label alone
textfontit / rm …Font of the descriptive text alone
justificationjustified / centering / raggedrightAlignment; justified is the default
widtha length (e.g. 0.8\textwidth)Narrow the width the caption wraps within
singlelinechecktrue / falseOn by default; centres any one-line caption regardless of justification

That last key, singlelinecheck, is the default most likely to surprise you. If you wrote justification=raggedright and yet the short captions keep centring themselves, this is why: any caption that fits on one line is centred automatically. Add singlelinecheck=false to keep them flush left. To style figures and tables differently, name the float type in square brackets: \captionsetup[figure]{…} and \captionsetup[table]{…}. Journal templates often carry a \captionsetup of their own, so before adding yours it is worth checking that you are not overriding theirs.

latex
\usepackage{caption}
\captionsetup{labelfont=bf, labelsep=period, font=small,
              justification=raggedright, singlelinecheck=false}

% different rules per float type
\captionsetup[figure]{justification=centering}
\captionsetup[table]{font=footnotesize}

Captioning something that is not a float: \captionof

When a figure must stay at this exact point in the text rather than float, but you still want normal numbering and references, the command is \captionof{type}{text}. Inside a minipage or center, where plain \caption refuses to work, \captionof{figure}{…} advances the figure counter, adds a line to the list of figures, and lets \ref resolve correctly. Compile it inside a minipage and, if the preceding float was “Figure 1”, this one duly becomes “Figure 2” and gains its own entry in the .lof. The point of the command is precisely that: drop the float machinery, keep the numbering machinery.

One caveat: \captionof is not a standard LaTeX command, so writing it without loading caption gives you ! Undefined control sequence. If you want the command but not the package's styling, the lightweight capt-of package provides \captionof on its own. And the rule about ordering does not change here either — with \captionof too, \label goes after it.

latex
\usepackage{caption}   % or the lightweight capt-of

\begin{center}
  \includegraphics[width=0.5\textwidth]{diagram}
  \captionof{figure}{A figure fixed in the text, outside any float}
  \label{fig:inline}
\end{center}

Splitting a figure into (a) and (b) with subcaption

To set small figures side by side inside one figure, each with its own (a), (b), (c) sub-label, the current standard is the subcaption package — Sommerfeldt's again. Writing \usepackage{subcaption} loads caption underneath, so there is no need to name both. The main tool is the subfigure environment (subtable for tables), which takes a mandatory width, as in \begin{subfigure}[b]{0.45\textwidth}. It is effectively a minipage, and you fill it with an \includegraphics and a \caption. A \caption inside a subfigure becomes the (a)/(b) sub-label; the \caption outside them numbers the figure as a whole.

latex
\usepackage{graphicx}
\usepackage{subcaption}   % loads caption itself

\begin{figure}
  \centering
  \begin{subfigure}[b]{0.45\textwidth}
    \centering
    \includegraphics[width=\linewidth]{before}
    \caption{Before}
    \label{fig:before}
  \end{subfigure}
  \hfill
  \begin{subfigure}[b]{0.45\textwidth}
    \centering
    \includegraphics[width=\linewidth]{after}
    \caption{After}
    \label{fig:after}
  \end{subfigure}
  \caption{Before and after processing}
  \label{fig:compare}
\end{figure}

Compile that and the whole figure becomes “Figure 1” while the two subfigures are set as “(a) Before” and “(b) After”. From the text, \ref{fig:compare} returns “1” and \ref{fig:before} returns “1a” — a reference to a subfigure is the figure number joined to the sub-label. When you want the sub-label alone, \subref{fig:before} gives a bare “a” and \subref*{fig:before} gives “(a)”. There is also a one-line form, \subcaptionbox[list entry]{heading}[width][inner pos]{contents}. Its syntax puts the \label inside the heading argument, as in \subcaptionbox{Before\label{fig:before}}{\includegraphics{…}}. For a subfigure that holds nothing but one image, it is shorter than several lines of minipage.

subfigure, subfig, subcaption: three generations and a silent clash

Subfigure packages come in three generations, and their similar names keep causing mix-ups. The oldest, subfigure, is obsolete and uses a \subfigure command; its successor subfig supplies \subfloat but is no longer actively maintained either. New documents should use subcaption. The trouble arises mid-migration: you add subcaption without noticing that the template already loads subfig.

What makes the clash nasty is that nothing happens at load time. List both in the preamble and subcaption merely writes an informational line to the log — Package subcaption Info: The counter 'subfigure' was already defined by... — with no warning and no error. It then quietly gives up defining its own subfigure environment. The document proceeds happily until the first \begin{subfigure}, at which point it collapses with ! LaTeX Error: Environment subfigure undefined. followed by a cascade of Missing number and Illegal unit of measure. In other words, the place the error appears is not the place that caused it. When you see this pattern, search the whole preamble for subfig and subfigure first — the odds are highest when you are working inside a journal template.

  • subcaption — the current standard: subfigure / subtable environments, \subcaptionbox, \subref. Loads caption for you.
  • subfig — the previous generation, with \subfloat. Fine in existing documents; do not choose it for new ones.
  • subfigure — the oldest, with \subfigure. Obsolete; do not use it.
  • Never combine them — exactly one. Check whether the template already loads one before adding another.