フロートと配置

「図を書いた場所に出てこない」「表が数ページ先に飛んだ」——これは LaTeX のバグではなく、figuretableフロート(floating object) だからです。LaTeX は図表を本文の流れから切り離し、ページのレイアウトが最も整う場所へ自動で「浮かせて」配置します。このページでは、その配置をどこまで指示できるのか——[htbp]配置指定子、流れを堰き止める \FloatBarrier\clearpage、二つの図を横に並べる方法、そして本文を回り込ませる wrapfig——を順に見ていきます。

フロートとは何か

図や表は、本文の途中で改ページにまたがると不格好です。半分だけ載って残りが次ページ、というわけにはいきません。そこで LaTeX は、図表を 一つのまとまり(ボックス) として扱い、本文の組版が一段落したところで、ページの上や下、あるいは図表だけのページに、自動で配置場所を選んで 流し込みます。これがフロートです。figuretable の二つが標準のフロート環境で、それぞれ図と表のために用意されています。

フロートには良い面と戸惑う面があります。良い面は、図表が改ページで割れず、番号付け(「図 1」「表 2」)と \caption\label\ref による相互参照が自動でそろうこと。戸惑う面は、書いた位置と出力位置がずれる こと。本文に \ref{fig:foo} で「図 1 参照」と書けるからこそ、図そのものは必ずしも近くに置かなくてよい、という設計なのです。だから原則は 「位置で示すのではなく、番号で参照する」\input で取り込む構成や、図そのものの作り方は別ページに譲り、ここでは「出る場所」に集中します。

配置指定子 `[htbp]`

figuretable 環境には、配置指定子(placement specifier) という省略可能な引数を渡せます。\begin{figure}[htbp] のように角括弧で、LaTeX に「ここに置いてよい候補」を伝えるものです。指定子は次の文字を組み合わせて書きます。

指定子意味備考
hhere(ここ)本文中の現在位置の近く。単独 h は不可で、LaTeX が自動的に t を補う
ttop(上)ページ上端
bbottom(下)ページ下端
ppage(フロート専用ページ)本文を含まず、フロートだけを集めた独立ページ
!制限の解除このフロートに限り、個数や本文/フロート比率の内部制限を無視させる
H真にここ(floatしない)float パッケージが追加。浮かせず、書いた位置に固定

指定子を省略すると、articlebook などでは既定値の **tbp** が使われます(h は含まれません)。複数並べると、LaTeX はその中の「どれか置けるところ」を探します。重要な落とし穴がふたつ。第一に、**h 単独はほぼ無視されます**。LaTeX は h を許しておらず、内部で t を補うため、[h] と書いても上に飛ぶことがよくあります。「本当にここ」が必要なら、後述の [H](float パッケージ)を使います。

第二に、指定子に書いた文字の順序は、試す順序を変えません[bt] と書いても [tb] と書いても、LaTeX が候補を試す順番(おおむね「ここ→上→下→専用ページ」)は同じです。順序は「許可した位置の集合」を表すだけだと考えてください。また 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] がふさわしいのは、手順説明の図など「文中の特定の位置に必ず居てほしい」小さな図表に限られます。なお [H]\floatplacement{figure}{H} で文書全体の既定にもできますが、上記の理由から推奨はしません。

流れを堰き止める——`\FloatBarrier` と `\clearpage`

フロートで一番困るのは、ある節の図がページに収まらず、次の節(や章)まで流れていく 現象です。第 2 節の図 3 が第 3 節の本文の途中に現れると、読者は混乱します。これを防ぐには、フロートが越えてはならない 「堰(barrier)」 を置きます。

placeins パッケージが提供する \FloatBarrier がそれです。この命令を置くと、それまでに 未処理だったフロートがすべてその手前で出力 され、以降のフロートは堰を越えられません。節ごとに区切りたいなら、各 \section の前に \FloatBarrier を書くか、\usepackage[section]{placeins} と読み込んで \section の先頭に堰を自動挿入させます。

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

\FloatBarrier と似て非なるのが **\clearpage** です。違いは改ページの有無にあります。\clearpage未処理のフロートをすべて出力したうえで改ページ しますが、\FloatBarrierフロートを出力するだけで改ページはしません。つまり同じページ内で堰だけを設けたいなら \FloatBarrier、章末などでページごと区切ってよいなら \clearpage、と使い分けます。なお [section] 既定の堰は厳格で、フロートが節の範囲を少しでもはみ出すのを禁じますが、[above][below] オプションで緩められます。

もう少し踏み込むと、LaTeX の自動配置は フロート配置パラメータ に従って動きます。これらは「ページのどれだけをフロートが占めてよいか」を比率で決める内部の数値で、思い通りに置けないときの最終調整に使えます(多くの場合はパラメータより [htbp] の見直しが先です)。

パラメータ既定値意味
\topfraction0.7ページ上部をフロートが占めてよい最大割合
\bottomfraction0.3ページ下部をフロートが占めてよい最大割合
\textfraction0.2本文ページに最低限残す本文の割合
\floatpagefraction0.5フロート専用ページを作る最小占有率
topnumber2ページ上部に置けるフロートの最大数
bottomnumber1ページ下部に置けるフロートの最大数
totalnumber31 ページに置けるフロートの最大数

比率は \renewcommand{\topfraction}{0.85} のように、整数のカウンタは \setcounter{totalnumber}{5} のように変更します。たとえば \topfraction を大きく \textfraction を小さくすると、ページ上部により多くの図表が載るようになり、「ここに入りきらないから次ページへ」という追い出しが減ります。! 指定子(前出)は、このフロートに限ってこれらの制限を一時的に無視させる、いわば局所版の調整です。

二つを横に並べる

二つの図(や表)を左右に並べたいことはよくあります。フロートは内部に好きな中身を置けるので、**一つの 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 がそのミニページの幅を指すので、\includegraphics[width=\linewidth] は箱いっぱいに画像を収めます。minipage ごとに \caption を置いたので「図 1」「図 2」と 別々の番号 が付きます。一つの図として一括りにしたいなら、\captionfigure 直下に一つだけ置きます。

左右を「図 2(a)」「図 2(b)」のように 一つの図の小図 として番号付けしたいなら、subcaption パッケージの subfigure 環境を使います(minipage とよく似た書き方で、\subcaption または環境内の \caption が (a)(b) を振ります)。サブ図やキャプションの詳しい扱いは別ページ「キャプションとサブ図」にまとめてあります。表を横に並べる場合も考え方は同じで、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 / R右(right)小文字 r=その場、大文字 R=浮動可
l / L左(left)小文字 l=その場、大文字 L=浮動可
i / I内側(inner)綴じ側。両面 twoside のとき有効
o / O外側(outer)小口側。両面 twoside のとき有効

上の例では、幅 0.4\textwidth の図が本文の 右側 に置かれ、続く 12 行 がその左を回り込みます。[34pt] の分だけ図は右マージンへはみ出します。行数 [12] を省くと、wrapfig は図の高さから回り込む行数を自分で見積もります(見積もりが外れて回り込みが乱れるときは明示すると安定します)。両面印刷で「綴じと反対側に置きたい」なら o(外側)を使うと、左右ページで自動的に振り分けられます。

wrapfig は便利な反面、癖が強い ので注意点を押さえておきましょう。マニュアルは次のように戒めています。

  • リストの中・直前・直後では使わない。 itemizeenumeratedescription などのリスト環境の内部、およびそのすぐ前後に置いてはいけません。
  • 改ページをまたがせない。 環境は、回り込みが改ページに割れない位置に置く必要があります。ページの境目付近は避けましょう。
  • 見出しや大きな数式を回り込ませない。 見栄えのため、回り込むのは普通の本文だけにします。節見出しや別行立ての数式は不格好になります。
  • 段落の途中より、段落の境目で開始する方が安定します。 また minipageparbox の中で使うときは、回り込みがそのグループの終わりより前で終わるようにします。

うまく回り込まないときは、図の幅を少し狭める、行数を明示する、開始位置を一段落ずらす、のいずれかでたいてい解決します。それでも整わない場合は、wrapfig をやめて素直にフロート([htbp])で上下に置く方が、結果的に読みやすいこともあります。