플로트와 배치

그림이 작성한 위치에 나타나지 않거나 표가 몇 페이지 뒤로 밀려나는 일은 LaTeX 버그가 아닙니다. figuretable플로트(floating object)이기 때문입니다. LaTeX는 그림과 표를 본문 흐름에서 떼어 내어 페이지 배치가 가장 잘 맞는 곳으로 “띄워” 배치합니다. 이 페이지에서는 [htbp]배치 지정자, 흐름을 막는 \FloatBarrier\clearpage, 두 그림을 나란히 놓는 방법, 그림 주위로 본문을 감싸는 wrapfig 패키지까지, 배치를 얼마나 조정할 수 있는지 차례로 살펴봅니다.

플로트란 무엇인가

그림이나 표가 페이지 나눔에 걸치면 보기 좋지 않습니다. 절반은 여기, 나머지는 다음 페이지에 둘 수는 없습니다. 그래서 LaTeX는 각 그림과 표를 하나의 상자로 다루고, 본문 일부를 조판한 뒤 페이지 위쪽이나 아래쪽, 또는 플로트 전용 페이지 중에서 자동으로 위치를 선택해 넣습니다. 이것이 플로트입니다. 표준 플로트 환경은 그림용 figure와 표용 table 두 가지입니다.

플로트에는 장점과 헷갈리는 점이 함께 있습니다. 장점은 그림이 페이지 사이에서 잘리지 않고, 번호(“Figure 1”, “Table 2”)와 \caption, \label, \ref를 통한 상호 참조가 자동으로 맞춰진다는 것입니다. 헷갈리는 점은 작성한 위치와 출력되는 위치가 다르다는 것입니다. 본문에서 \ref{fig:foo}로 “Figure 1 참조”라고 쓸 수 있으므로, 그림 자체가 반드시 그 문장 바로 옆에 있을 필요는 없다는 설계입니다. 따라서 원칙은 위치가 아니라 번호로 참조하기입니다. \input으로 파일을 나누는 구성이나 그림 자체를 만드는 방법은 다른 페이지에서 다루고, 여기서는 플로트가 나오는 위치에만 집중합니다.

[htbp] 배치 지정자

figuretable 환경에는 배치 지정자(placement specifier)라는 선택 인수를 줄 수 있습니다. \begin{figure}[htbp]처럼 대괄호 안에 써서 LaTeX가 사용할 수 있는 위치 후보를 알려 줍니다. 다음 글자들을 조합해 씁니다.

지정자의미비고
hhere본문의 현재 위치 근처. h 단독은 허용되지 않아 LaTeX가 자동으로 t를 더합니다
ttop텍스트 페이지의 위쪽
bbottom텍스트 페이지의 아래쪽
ppage본문 없이 플로트만 모은 별도 플로트 페이지
!override이 플로트에 한해 개수와 플로트/본문 비율 제한을 무시합니다
H정말 여기(플로트하지 않음)float 패키지가 제공하며, 띄우지 않고 작성한 위치에 고정합니다

지정자를 생략하면 article, book 같은 클래스는 기본값 tbp를 사용합니다(h 없음). 여러 글자를 나열하면 LaTeX는 그중 사용할 수 있는 위치를 찾습니다. 중요한 함정이 두 가지 있습니다. 첫째, h 단독은 대체로 무시됩니다. LaTeX는 bare h를 허용하지 않고 조용히 t를 더하므로 [h]라고 써도 결국 위쪽으로 이동하는 일이 많습니다. 정말 “바로 여기”가 필요하다면 아래에서 설명하는 float 패키지의 [H]를 사용합니다.

둘째, 지정자에 쓴 글자의 순서는 LaTeX가 시도하는 순서를 바꾸지 않습니다. [bt]라고 쓰든 [tb]라고 쓰든 LaTeX가 후보를 시도하는 순서는 같습니다(대략 here → top → bottom → float page). 글자는 허용한 위치의 *집합*일 뿐이라고 생각하면 됩니다. 또한 LaTeX는 플로트를 소스에 나타난 순서대로 처리하므로 뒤의 그림이 앞의 그림을 앞질러 나올 수도 있습니다. 실전에서는 너무 제한하지 않는 것이 좋습니다. [tbp][htbp]처럼 넓게 허용할수록 LaTeX는 플로트를 근처에 더 잘 배치합니다. 한 글자, 특히 [h]로 좁히면 오히려 더 멀리 밀려나는 경향이 있습니다.

latex
\begin{figure}[htbp]
  \centering
  \includegraphics[width=0.6\textwidth]{plot}
  \caption{実験結果}
  \label{fig:result}
\end{figure}

図~\ref{fig:result} に結果を示す。

이 예에서 [htbp]는 현재 위치, 위쪽, 아래쪽, 플로트 페이지 중 어느 곳이든 허용하고 LaTeX가 최적의 위치를 고릅니다. 그림을 가운데 맞추는 \centering, 제목과 번호를 붙이는 \caption, 참조용 \label은 플로트의 전형적인 내용입니다. 본문은 図~\ref{fig:result}처럼 번호로 참조하므로, 그림이 조금 떨어진 곳에 출력되어도 문장은 자연스럽게 유지됩니다(~는 단어와 번호가 줄 끝에서 갈라지지 않게 하는 줄바꿈 없는 공백입니다).

여기에 강제로 고정하기 — [H]

플로트를 정말로 “작성한 바로 그 위치”에 두어야 한다면, 프리앰블에서 float 패키지를 불러오고 대문자 [H]를 사용합니다. [H]는 일반 배치 문자가 아닙니다. 플로팅을 완전히 끄고 그림이나 표를 그 자리에 고정합니다. 동작은 그 위치에 큰 상자를 바로 놓는 것과 거의 같습니다.

latex
\usepackage{float}
% ...
\begin{figure}[H]
  \centering
  \includegraphics[width=0.6\textwidth]{diagram}
  \caption{処理の流れ}
\end{figure}

다만 [H]는 마지막 수단으로 생각하세요. 플로트를 고정하면 페이지 아래쪽에 들어가지 않을 때 큰 빈 공간이 남거나, 플로트가 다음 페이지 맨 위로 밀려 현재 페이지 아래가 비어 버릴 수 있습니다. LaTeX의 자동 배치를 믿고 [htbp]로 넓게 허용하는 편이 대체로 더 깔끔합니다. [H]가 제값을 하는 경우는 단계별 설명 그림처럼 본문 속 특정 지점에 반드시 있어야 하는 작은 그림이나 표로 한정됩니다. \floatplacement{figure}{H}로 문서 전체 기본값을 [H]로 만들 수도 있지만, 위 이유 때문에 권장하지 않습니다.

흐름 막기 — \FloatBarrier\clearpage

가장 곤란한 플로트 문제는 어떤 절의 그림이 그 절 안에 들어가지 못해 다음 절이나 다음 장으로 흘러가는 현상입니다. 2절의 Figure 3이 3절 본문 중간에 나타나면 독자는 혼란스러워집니다. 이를 막으려면 플로트가 넘어갈 수 없는 장벽(barrier)을 둡니다.

그 장벽이 placeins 패키지의 \FloatBarrier입니다. 이 명령을 둔 위치에서는 아직 처리되지 않은 모든 플로트가 그 앞에서 출력되고, 이후의 플로트도 이 장벽을 넘을 수 없습니다. 절 단위로 플로트를 막고 싶다면 각 \section 앞에 \FloatBarrier를 쓰거나, \usepackage[section]{placeins}를 불러 각 \section 시작에 장벽을 자동 삽입하게 합니다.

latex
\usepackage{placeins}
% ...
\section{実験}
% ... 図や表 ...
\FloatBarrier   % ここより先へフロートを越えさせない
\section{考察}

\clearpage는 비슷하지만 다른 명령이며, 차이는 페이지 나눔입니다. \clearpage대기 중인 모든 플로트를 출력한 뒤 새 페이지를 시작하지만, \FloatBarrier플로트를 출력할 뿐 페이지를 나누지 않습니다. 따라서 같은 페이지 안에서 장벽만 두고 싶다면 \FloatBarrier, 장 끝처럼 페이지를 완전히 끊어도 된다면 \clearpage를 사용합니다. [section] 장벽은 기본적으로 엄격해서 플로트가 절 범위를 조금이라도 벗어나는 것을 금지하지만, [above][below] 옵션으로 완화할 수 있습니다.

조금 더 들어가면 LaTeX의 자동 배치는 플로트 배치 매개변수를 따릅니다. 이는 한 페이지에서 플로트가 차지해도 되는 비율을 정하는 내부 수치입니다. 원하는 대로 배치되지 않을 때 마지막 조정 수단으로 쓸 수 있지만, 대부분은 먼저 [htbp]를 다시 보는 것이 좋습니다.

매개변수기본값의미
\topfraction0.7페이지 위쪽에서 플로트가 차지할 수 있는 최대 비율
\bottomfraction0.3페이지 아래쪽에서 플로트가 차지할 수 있는 최대 비율
\textfraction0.2텍스트 페이지에 본문으로 남아야 하는 최소 비율
\floatpagefraction0.5별도 플로트 페이지를 만들기 전 필요한 최소 점유율
topnumber2페이지 위쪽에 둘 수 있는 플로트 최대 개수
bottomnumber1페이지 아래쪽에 둘 수 있는 플로트 최대 개수
totalnumber3한 페이지에 둘 수 있는 플로트 최대 개수

비율은 \renewcommand{\topfraction}{0.85}처럼, 정수 카운터는 \setcounter{totalnumber}{5}처럼 바꿉니다. 예를 들어 \topfraction을 높이고 \textfraction을 낮추면 페이지 위쪽에 더 많은 그림과 표가 올라갈 수 있어 “여기에 안 들어가니 다음 페이지로” 밀리는 일이 줄어듭니다. 앞서 본 ! 지정자는 사실 이 조정의 국소 버전으로, 이 플로트 하나에 대해서만 이러한 제한을 무시하라고 LaTeX에 지시합니다.

두 개를 나란히 놓기

두 그림이나 표를 좌우로 나란히 두고 싶을 때가 많습니다. 플로트 안에는 원하는 내용을 넣을 수 있으므로 기본 아이디어는 하나의 figure 안에 나란한 상자 두 개를 만드는 것입니다. 순수 LaTeX만으로는 minipage를 쓰고, 하위 그림에 (a), (b) 같은 번호를 붙이고 싶다면 subcaption 패키지를 사용합니다.

minipage는 지정한 너비의 “작은 페이지”를 만드는 환경입니다. 두 개를 가로로 놓고 사이에 \hfill(늘어나고 줄어드는 수평 여백)을 넣으면 좌우로 벌어집니다. 각각의 너비를 본문 너비의 절반보다 조금 작게, 예를 들어 0.48\textwidth로 하여 합계가 전체 너비보다 약간 작게 유지되도록 하는 것이 요령입니다.

latex
\begin{figure}[htbp]
  \centering
  \begin{minipage}{0.48\textwidth}
    \centering
    \includegraphics[width=\linewidth]{left}
    \caption{左の図}
    \label{fig:left}
  \end{minipage}
  \hfill
  \begin{minipage}{0.48\textwidth}
    \centering
    \includegraphics[width=\linewidth]{right}
    \caption{右の図}
    \label{fig:right}
  \end{minipage}
\end{figure}

이 예에서는 figure 안에 너비 0.48\textwidthminipage 두 개가 놓이고, 사이의 \hfill이 남는 공간을 바깥쪽으로 밀어 양끝에 붙게 합니다. 각 minipage 안에서 \linewidth는 그 minipage의 너비를 뜻하므로 \includegraphics[width=\linewidth]는 상자를 가득 채웁니다. 각 minipage마다 \caption을 두었기 때문에 “Figure 1”, “Figure 2”처럼 별도의 번호가 붙습니다. 두 개를 하나의 그림으로 취급하려면 figure 바로 아래에 \caption을 하나만 둡니다.

좌우를 “Figure 2(a)”, “Figure 2(b)”처럼 하나의 그림 안의 하위 그림으로 번호 매기고 싶다면 subcaption 패키지의 subfigure 환경을 사용합니다(minipage와 매우 비슷하게 쓰며, 내부의 \subcaption 또는 \caption이 (a)/(b) 라벨을 만듭니다). 하위 그림과 caption의 자세한 처리는 별도 “Captions & subfigures” 페이지에서 다룹니다. 표를 나란히 놓을 때도 생각은 같아서, 각 minipage 안에 tabular를 둡니다.

그림 주위로 본문 감싸기 — wrapfig

작은 그림의 옆 여백으로 본문이 감싸 흐르게 하고 싶다면, 잡지 기사에서 자주 보이는 그 배치에는 wrapfig 패키지의 wrapfigure 환경을 사용합니다(표라면 wraptable). 문법은 다음과 같습니다.

latex
\usepackage{wrapfig}
% ...
\begin{wrapfigure}[12]{r}[34pt]{0.4\textwidth}
  \centering
  \includegraphics[width=0.38\textwidth]{portrait}
  \caption{人物像}
\end{wrapfigure}

인수는 네 개이고, 그중 두 개가 필수입니다. {r}배치(어느 쪽에 둘지), 마지막 {0.4\textwidth}그림의 너비입니다. 중간의 선택 인수 [12]는 감쌀 줄 수, [34pt]는 그림이 판면 바깥쪽 여백으로 얼마나 튀어나갈지를 뜻하는 오버행입니다. 배치 문자는 짝을 이루며, 소문자는 그 자리에 고정하고 대문자는 플로트로 떠다니는 것을 허용합니다.

글자비고
r / Rrightr = 여기, R = 플로트 가능
l / Lleftl = 여기, L = 플로트 가능
i / Iinner제본 쪽. twoside 문서에서 사용
o / Oouter제본 반대쪽. twoside 문서에서 사용

위 예에서는 너비 0.4\textwidth인 그림이 본문의 오른쪽에 놓이고, 이어지는 12줄이 그 왼쪽을 감싸 흐릅니다. [34pt]만큼 그림은 오른쪽 여백으로 튀어나갑니다. 줄 수 [12]를 생략하면 wrapfig는 그림 높이로부터 감쌀 줄 수를 추정합니다(추정이 빗나가 감싸기가 흐트러질 때는 명시하면 안정됩니다). 양면 인쇄에서 제본 반대쪽에 두고 싶다면 o(outer)를 쓰면 왼쪽 페이지와 오른쪽 페이지 사이에서 자동으로 방향이 바뀝니다.

wrapfig는 편리하지만 다루기 까다로운 면이 있으므로 주의점을 알아 두어야 합니다. 매뉴얼은 요지를 다음과 같이 경고합니다.

  • 목록 안이나 목록 바로 앞뒤에서 사용하지 마세요. itemize, enumerate, description 같은 목록 환경 안과 그 직전·직후는 피합니다.
  • 페이지 나눔을 가로지르게 하지 마세요. 감싸기가 페이지 사이에서 갈라지지 않는 위치에 환경을 두고, 페이지 경계 근처는 피합니다.
  • 제목이나 큰 수식이 감싸도록 하지 마세요. 보기 좋게 하려면 일반 본문만 감싸야 하며, 절 제목과 별행 수식은 좋지 않게 나옵니다.
  • 단락 중간보다 단락 경계에서 시작하는 편이 안정적입니다. minipageparbox 안에서 사용할 때는 감싸기가 그 그룹의 끝보다 먼저 끝나도록 합니다.

감싸기가 잘 동작하지 않을 때는 그림 너비를 조금 줄이거나, 줄 수를 명시하거나, 시작 위치를 한 단락 옮기는 것으로 대개 해결됩니다. 그래도 정리되지 않으면 wrapfig를 포기하고 일반 플로트([htbp]로 본문 위나 아래에 배치)를 쓰는 편이 결과적으로 더 읽기 쉬울 수도 있습니다.