「図を書いた場所に出てこない」「表が数ページ先に飛んだ」——これは LaTeX のバグではなく、figure・table が フロート(floating object) だからです。LaTeX は図表を本文の流れから切り離し、ページのレイアウトが最も整う場所へ自動で「浮かせて」配置します。このページでは、その配置をどこまで指示できるのか——[htbp] の 配置指定子、流れを堰き止める \FloatBarrier と \clearpage、二つの図を横に並べる方法、そして本文を回り込ませる wrapfig——を順に見ていきます。
フロートとは何か
図や表は、本文の途中で改ページにまたがると不格好です。半分だけ載って残りが次ページ、というわけにはいきません。そこで LaTeX は、図表を 一つのまとまり(ボックス) として扱い、本文の組版が一段落したところで、ページの上や下、あるいは図表だけのページに、自動で配置場所を選んで 流し込みます。これがフロートです。figure と table の二つが標準のフロート環境で、それぞれ図と表のために用意されています。
フロートには良い面と戸惑う面があります。良い面は、図表が改ページで割れず、番号付け(「図 1」「表 2」)と \caption・\label・\ref による相互参照が自動でそろうこと。戸惑う面は、書いた位置と出力位置がずれる こと。本文に \ref{fig:foo} で「図 1 参照」と書けるからこそ、図そのものは必ずしも近くに置かなくてよい、という設計なのです。だから原則は 「位置で示すのではなく、番号で参照する」。\input で取り込む構成や、図そのものの作り方は別ページに譲り、ここでは「出る場所」に集中します。
配置指定子 `[htbp]`
figure・table 環境には、配置指定子(placement specifier) という省略可能な引数を渡せます。\begin{figure}[htbp] のように角括弧で、LaTeX に「ここに置いてよい候補」を伝えるものです。指定子は次の文字を組み合わせて書きます。
| 指定子 | 意味 | 備考 |
|---|---|---|
h | here(ここ) | 本文中の現在位置の近く。単独 h は不可で、LaTeX が自動的に t を補う |
t | top(上) | ページ上端 |
b | bottom(下) | ページ下端 |
p | page(フロート専用ページ) | 本文を含まず、フロートだけを集めた独立ページ |
! | 制限の解除 | このフロートに限り、個数や本文/フロート比率の内部制限を無視させる |
H | 真にここ(floatしない) | float パッケージが追加。浮かせず、書いた位置に固定 |
指定子を省略すると、article・book などでは既定値の **tbp** が使われます(h は含まれません)。複数並べると、LaTeX はその中の「どれか置けるところ」を探します。重要な落とし穴がふたつ。第一に、**h 単独はほぼ無視されます**。LaTeX は h を許しておらず、内部で t を補うため、[h] と書いても上に飛ぶことがよくあります。「本当にここ」が必要なら、後述の [H](float パッケージ)を使います。
第二に、指定子に書いた文字の順序は、試す順序を変えません。[bt] と書いても [tb] と書いても、LaTeX が候補を試す順番(おおむね「ここ→上→下→専用ページ」)は同じです。順序は「許可した位置の集合」を表すだけだと考えてください。また LaTeX は ソース中に現れた順序 でフロートを処理するため、後ろの図が先に出る「追い越し」も起こりえます。だから実用上は、選択肢を狭めすぎないこと——[tbp] や [htbp] のように広く許すほど、LaTeX は素直に近くへ置けます。一文字だけ(とくに [h])に絞ると、かえって遠くへ飛びがちです。
\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] は普通の配置指定子とは別物で、フロートとしての浮動をやめさせ、図表をその場に 固定 します。挙動はほぼ「ここに大きなボックスを置く」のと同じです。
\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 の先頭に堰を自動挿入させます。
\usepackage{placeins}
% ...
\section{実験}
% ... 図や表 ...
\FloatBarrier % ここより先へフロートを越えさせない
\section{考察}\FloatBarrier と似て非なるのが **\clearpage** です。違いは改ページの有無にあります。\clearpage は 未処理のフロートをすべて出力したうえで改ページ しますが、\FloatBarrier は フロートを出力するだけで改ページはしません。つまり同じページ内で堰だけを設けたいなら \FloatBarrier、章末などでページごと区切ってよいなら \clearpage、と使い分けます。なお [section] 既定の堰は厳格で、フロートが節の範囲を少しでもはみ出すのを禁じますが、[above]・[below] オプションで緩められます。
もう少し踏み込むと、LaTeX の自動配置は フロート配置パラメータ に従って動きます。これらは「ページのどれだけをフロートが占めてよいか」を比率で決める内部の数値で、思い通りに置けないときの最終調整に使えます(多くの場合はパラメータより [htbp] の見直しが先です)。
| パラメータ | 既定値 | 意味 |
|---|---|---|
\topfraction | 0.7 | ページ上部をフロートが占めてよい最大割合 |
\bottomfraction | 0.3 | ページ下部をフロートが占めてよい最大割合 |
\textfraction | 0.2 | 本文ページに最低限残す本文の割合 |
\floatpagefraction | 0.5 | フロート専用ページを作る最小占有率 |
topnumber | 2 | ページ上部に置けるフロートの最大数 |
bottomnumber | 1 | ページ下部に置けるフロートの最大数 |
totalnumber | 3 | 1 ページに置けるフロートの最大数 |
比率は \renewcommand{\topfraction}{0.85} のように、整数のカウンタは \setcounter{totalnumber}{5} のように変更します。たとえば \topfraction を大きく \textfraction を小さくすると、ページ上部により多くの図表が載るようになり、「ここに入りきらないから次ページへ」という追い出しが減ります。! 指定子(前出)は、このフロートに限ってこれらの制限を一時的に無視させる、いわば局所版の調整です。
二つを横に並べる
二つの図(や表)を左右に並べたいことはよくあります。フロートは内部に好きな中身を置けるので、**一つの figure のなかに横並びの箱を二つ作る** のが基本です。素の LaTeX だけでできる方法が minipage、サブ図に番号((a)・(b))を振りたいなら subcaption パッケージを使います。
minipage は、指定した幅の「小さなページ」を作る環境です。これを二つ横に置き、間に \hfill(伸び縮みする水平の空き)を挟むと、左右に振り分けられます。それぞれの幅を本文幅の半分弱(たとえば 0.48\textwidth)にして、合計が本文幅を少し下回るようにするのがコツです。
\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\textwidth の minipage が二つ並び、間の \hfill が余白を左右に押し広げて両端に寄せます。各 minipage のなかでは \linewidth がそのミニページの幅を指すので、\includegraphics[width=\linewidth] は箱いっぱいに画像を収めます。minipage ごとに \caption を置いたので「図 1」「図 2」と 別々の番号 が付きます。一つの図として一括りにしたいなら、\caption は figure 直下に一つだけ置きます。
左右を「図 2(a)」「図 2(b)」のように 一つの図の小図 として番号付けしたいなら、subcaption パッケージの subfigure 環境を使います(minipage とよく似た書き方で、\subcaption または環境内の \caption が (a)(b) を振ります)。サブ図やキャプションの詳しい扱いは別ページ「キャプションとサブ図」にまとめてあります。表を横に並べる場合も考え方は同じで、minipage のなかに tabular を置きます。
本文を回り込ませる——`wrapfig`
小さな図の左右の余白に本文を回り込ませたい——雑誌記事でよく見るあのレイアウトには、wrapfig パッケージの wrapfigure 環境(表なら wraptable)を使います。構文は次の形です。
\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 は便利な反面、癖が強い ので注意点を押さえておきましょう。マニュアルは次のように戒めています。
- リストの中・直前・直後では使わない。
itemize・enumerate・descriptionなどのリスト環境の内部、およびそのすぐ前後に置いてはいけません。 - 改ページをまたがせない。 環境は、回り込みが改ページに割れない位置に置く必要があります。ページの境目付近は避けましょう。
- 見出しや大きな数式を回り込ませない。 見栄えのため、回り込むのは普通の本文だけにします。節見出しや別行立ての数式は不格好になります。
- 段落の途中より、段落の境目で開始する方が安定します。 また
minipageやparboxの中で使うときは、回り込みがそのグループの終わりより前で終わるようにします。
うまく回り込まないときは、図の幅を少し狭める、行数を明示する、開始位置を一段落ずらす、のいずれかでたいてい解決します。それでも整わない場合は、wrapfig をやめて素直にフロート([htbp])で上下に置く方が、結果的に読みやすいこともあります。