캡션과 하위 그림

모든 그림의 번호는 멀쩡한데 \ref만 다른 번호를 찍어 냅니다. LaTeX에서 가장 많이 보고되는 “그림 번호가 틀렸다”는 문제는 거의 언제나 \label\caption 앞에 쓴 데서 옵니다. 오류도 경고도 없고, 인쇄된 숫자만 조용히 거짓말을 합니다. 캡션 명령은 수수해 보이지만 번호 매기기, 상호 참조, 그림 목록 세 가지가 모두 여기서 정해집니다. 이 페이지에서는 \caption이 왜 플로트 안에서만 동작하는지, \label을 어디에 두어야 하는지, caption 패키지로 모양을 다듬는 법, 플로트 밖에서 쓰는 \captionof, 그리고 (a)(b)로 나누는 하위 그림을 다룹니다.

\caption이 플로트 안에서만 동작하는 이유

\caption{…}은 그림이나 표에 설명문을 붙이는 명령이지만 figuretable 안에서만 동작합니다. 본문에 그대로 쓰면 ! LaTeX Error: \caption outside float.로 멈춥니다. 이유는 이 명령이 단순히 글자를 조판하는 것이 아니라, 자신이 어떤 종류의 플로트 안에 있는지 살펴 해당 카운터를 올리기 때문입니다. figure 안이면 figure 카운터를, table 안이면 table 카운터를 올립니다. 플로트 밖에는 그 정보가 없으니 번호를 붙일 방법도 없습니다. 그래서 번호를 직접 쓸 필요가 전혀 없고, 써서도 안 됩니다.

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}

배치 관례도 짚어 둡니다. 그림의 캡션은 그림 아래, 표의 캡션은 표 위에 두는 것이 일반적입니다. 표는 위에서 아래로 읽으므로 무엇에 관한 표인지 먼저 알려 주는 편이 자연스럽기 때문입니다. LaTeX는 \caption을 쓴 위치에 그대로 조판하므로, 위에 내려면 그림보다 앞에, 아래에 내려면 뒤에 씁니다. 번호와 본문 사이 간격 같은 형식 자체는 위치에 따라 달라지지 않습니다. 다만 이 방향은 투고처 규정으로 정해져 있는 경우가 많으니, 먼저 학술지의 스타일 가이드를 확인하세요.

\label\caption 앞에 쓰면 무슨 일이 벌어지는가

\label은 반드시 \caption 뒤에 둡니다. \label은 “현재 번호”를 기록할 뿐이고, 그 현재 번호를 그림 번호로 바꾸는 것은 \caption입니다. 그래서 \caption보다 앞에 \label을 쓰면 마지막으로 움직인 카운터——대개 절 번호——가 그대로 기록됩니다. 실제로 5절 안에서 번호가 2가 되어야 할 그림에 \caption보다 앞선 \label을 붙여 조판하면, 보조 파일에는 \newlabel{fig:before}{{5}{1}...}가 적히고 본문에는 “그림 5”가 인쇄됩니다. 오류도 경고도 전혀 없습니다. 출력을 직접 눈으로 확인하지 않는 한 이 실수는 최종본까지 살아남습니다.

이 함정에는 정해진 모양이 있습니다. \includegraphics 바로 뒤에 \label을 쓰고 싶어지는 것이 인지상정입니다. 그림에 이름표를 다는 기분이 들기 때문입니다. 하지만 LaTeX에게 \label이 가리키는 것은 그림이 아니라 카운터이고, 그 카운터를 설정하는 것은 \caption입니다. 대책은 간단합니다. \caption\label을 반드시 붙어 있는 두 줄로 두는 것입니다. 사이에 아무것도 끼지 않으면 순서를 틀릴 여지가 없습니다. 하위 그림도 마찬가지여서, subfigure 안의 \label은 그 안의 \caption 뒤에 둡니다. \label\ref의 일반적인 구조는 상호 참조 페이지가 자세히 다룹니다.

짧은 제목과 그림 목록: \caption[...]{...}, \caption*, \ContinuedFloat

캡션이 길고 그림 목록에는 한 줄만 넣고 싶다면, 그것을 위한 선택 인수가 \caption[짧은 제목]{긴 본문}입니다. 대괄호 안의 내용은 \listoffigures 목록으로, 중괄호 안의 내용은 그림 옆으로 갑니다. 대괄호를 생략하면 본문 전체가 목록에도 흘러 들어가므로, 세 줄짜리 캡션을 가진 그림이 몇 개만 있어도 목차가 무너집니다. 시험 문서에서 \caption[Short entry for the list]{A long caption that is only shown under the figure}라고 쓰고 \listoffigures를 내면 .lof 파일에는 짧은 쪽만 기록됩니다. 수식이나 \cite가 든 긴 캡션에서는 대괄호 쪽을 소박한 문장으로 두면 목차 조판 사고도 막을 수 있습니다.

caption 패키지를 불러오면 두 가지 변종을 쓸 수 있습니다. \caption*{…}번호도 붙지 않고 목록에도 오르지 않는 캡션으로, 권두화나 장 표지 그림에 알맞습니다. \ContinuedFloat는 큰 그림을 여러 플로트로 나눌 때 앞 플로트의 번호를 그대로 이어받게 하는 명령입니다. \begin{figure} 첫머리에 \ContinuedFloat를 쓰고 \caption{Continued}라고 하면, 인쇄되는 것은 여전히 “그림 1”인 두 번째 장입니다. 여러 쪽에 걸친 큰 일람 그림을 번호를 늘리지 않고 나누고 싶을 때의 정석입니다.

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}

caption 패키지로 모양 다듬기: \captionsetup

글꼴, 번호와 본문 사이의 구분자, 정렬을 바꾸고 싶다면 caption 패키지를 씁니다. 작성자는 Axel Sommerfeldt이고, 저작권 표시는 1994년까지 거슬러 올라가며, TeX Live 2024에 들어 있는 것은 2023년 8월의 v3.6o입니다. 30년 동안 한 사람의 손에서 유지되어 온 도구인 셈입니다. \usepackage{caption}으로 불러오고 \captionsetup{키=값, …}으로 지정합니다. 이 명령의 핵심은 적용 범위입니다. 프리앰블에 쓰면 문서 전체, 플로트 안에 쓰면 그 캡션 하나에만 적용됩니다.

주요 값역할
formatplain / hang본문 조판 방식. hang은 둘째 줄부터 라벨 폭만큼 들여씀
labelsepcolon / period / space / quad / newline번호와 본문 사이의 구분자. 기본값은 colon
fontsmall / footnotesize / it …캡션 전체의 글꼴과 크기
labelfontbf / sc / it …“Figure 1” 라벨 부분만의 글꼴
textfontit / rm …설명문 본문만의 글꼴
justificationjustified / centering / raggedright정렬. 기본값은 양쪽 정렬
width길이(예: 0.8\textwidth)캡션이 줄바꿈되는 폭을 좁힘
singlelinechecktrue / false기본은 true. 한 줄짜리 캡션을 justification과 무관하게 가운데 정렬

마지막의 singlelinecheck은 의도와 어긋나기 쉬운 기본값입니다. justification=raggedright라고 썼는데도 짧은 캡션만 가운데로 몰리는 현상은 이 때문이며, 한 줄에 들어가는 캡션은 자동으로 가운데 정렬됩니다. 항상 왼쪽 정렬로 두려면 singlelinecheck=false를 덧붙이세요. 그림과 표의 모양을 나누고 싶다면 \captionsetup[figure]{…}, \captionsetup[table]{…}처럼 대괄호로 플로트 종류를 지정합니다. 학술지 템플릿이 이미 \captionsetup을 갖고 있는 경우도 많으니, 추가하기 전에 덮어쓰고 있지 않은지 확인하는 편이 안전합니다.

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}

플로트가 아닌 것에 캡션 붙이기: \captionof

플로트에 태우지 않고 그림을 본문의 바로 이 자리에 고정하고 싶지만 번호와 참조는 평소대로 쓰고 싶을 때, 그 명령이 \captionof{종류}{본문}입니다. \caption을 쓸 수 없는 minipagecenter 안에서도 \captionof{figure}{…}라고 쓰면 figure 카운터가 올라가고 그림 목록에도 오르며 \ref도 제대로 동작합니다. 실제로 minipage 안에서 조판해 보면, 앞선 플로트가 “그림 1”이었다면 이어서 “그림 2”가 되고 .lof에도 한 줄이 늘어납니다. 플로트 기구만 떼어 내고 번호 매기기 기구는 그대로 쓴다는 것이 이 명령의 요점입니다.

주의할 점 하나. \captionof는 LaTeX 표준 명령이 아니므로 caption을 불러오지 않고 쓰면 ! Undefined control sequence.가 납니다. 캡션 모양은 바꾸고 싶지 않고 이 명령만 필요하다면 가벼운 capt-of 패키지가 있어 \captionof만 제공합니다. 그리고 \captionof를 쓸 때도 \label은 그 뒤에 둔다는 규칙은 그대로입니다.

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}

subcaption으로 그림을 (a)(b)로 나누기

하나의 그림 안에 작은 그림을 나란히 두고 각각에 (a)(b)(c) 소제목을 붙이는 일, 현재의 표준은 subcaption 패키지이며 이 역시 Sommerfeldt의 작품입니다. \usepackage{subcaption}이라고 쓰면 뒤에서 caption도 함께 실리므로 둘 다 적을 필요는 없습니다. 주역은 subfigure 환경(표라면 subtable)으로, 폭을 필수 인수로 \begin{subfigure}[b]{0.45\textwidth}처럼 줍니다. 실질적으로 minipage이며 안에 \includegraphics\caption을 넣습니다. subfigure 안의 \caption은 (a)(b) 소제목이 되고, 바깥에 둔 \caption이 그림 전체의 번호를 맡습니다.

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}

이 예를 조판하면 그림 전체가 “그림 1”이 되고, 두 하위 그림은 “(a) Before”, “(b) After”가 됩니다. 본문에서 \ref{fig:compare}는 “1”을, \ref{fig:before}“1a”를 돌려줍니다. 하위 그림에 대한 참조는 그림 번호와 소제목을 이어 붙인 것입니다. (a) 부분만 필요하다면 \subref{fig:before}로 “a”, \subref*{fig:before}로 “(a)”를 얻습니다. 한 줄로 쓸 수 있는 \subcaptionbox[목록 제목]{소제목}[폭][내부 위치]{내용}도 있습니다. 이쪽은 문법상 \label을 소제목 인수 안에 넣는다는 점이 다르며, \subcaptionbox{Before\label{fig:before}}{\includegraphics{…}}처럼 씁니다. 이미지 한 장만 담는 하위 그림이라면 minipage를 여러 줄 쓰는 것보다 짧습니다.

subfigure・subfig・subcaption: 세 세대와 조용히 터지는 충돌

하위 그림 패키지는 세 세대가 있고, 이름이 비슷한 탓에 헷갈림이 끊이지 않습니다. 가장 오래된 subfigure는 폐기되었고 \subfigure 명령을 씁니다. 그 후계인 subfig\subfloat를 제공하지만 이 역시 더는 적극적으로 유지보수되지 않습니다. 새 문서는 subcaption을 고르세요. 문제는 이행 도중에 생깁니다. 템플릿이 이미 subfig를 불러오고 있는 줄 모르고 subcaption을 더하는 사고입니다.

이 충돌이 성가신 까닭은 불러오는 시점에는 아무 일도 일어나지 않는다는 데 있습니다. 둘을 프리앰블에 나란히 두어도 subcaption은 로그에 Package subcaption Info: The counter 'subfigure' was already defined by...라는 정보 줄만 남길 뿐, 경고도 오류도 내지 않습니다. 그러고는 자신의 subfigure 환경 정의를 조용히 포기합니다. 문서는 멀쩡히 진행되다가 첫 \begin{subfigure}에 이르는 순간 ! LaTeX Error: Environment subfigure undefined.로 무너지고, 뒤이어 Missing numberIllegal unit of measure가 줄줄이 따라옵니다. 즉 오류가 난 자리는 원인이 있는 자리가 아닙니다. 이 증상을 보면 먼저 프리앰블 전체에서 subfigsubfigure를 검색하세요. 학술지 템플릿을 쓰고 있다면 가능성이 특히 높습니다.

  • subcaption — 현재 표준. subfigure / subtable 환경, \subcaptionbox, \subref. caption을 자동으로 불러옵니다.
  • subfig — 이전 세대. \subfloat 명령. 기존 문서에서는 동작하지만 새 문서에는 고르지 않습니다.
  • subfigure — 가장 오래된 것. \subfigure 명령. 폐기되었으므로 쓰지 않습니다.
  • 함께 쓸 수 없음 — 반드시 하나만. 추가하기 전에 템플릿이 이미 불러오고 있지 않은지 확인합니다.