フロートが配置される場所をコントロールしたい

# フロートが配置される場所をコントロールしたい

図表を挿入する際、figure・table 環境などの floating 環境を利用します。これらの環境によって形成される構成要素を “**フロート**” [^floats] と呼びます。

[^floats]: あまり一般的ではないようですが、フロートは日本語では「浮動体」と呼ばれます。英語圏における “floating bodies” から来ています。しかし、日本で浮動体よりもフロートと呼ばれることが多いように、英語圏でも圧倒的に “floats” と呼ばれることの方が多いようです。

    個人的な観測では、“The Not So Short Introduction to LaTeX2ε” (lshort) でしか “floating bodies” という文言を見ることは出来ませんでした。

フロートは LaTeX によって自動的に、かつ執筆者にとって非自明的な場所に配置されます。そのため、執筆者にとって不都合な場所に配置されることもしばしばあります。

本記事では、フロートを執筆者側からある程度コントロールする方法を紹介します。

[afterpage]: https://www.ctan.org/pkg/afterpage "afterpage - CTAN"
[algorithm]: https://www.ctan.org/pkg/algorithm "algorithm - CTAN"
[caption]: https://www.ctan.org/pkg/caption "caption - CTAN"
[easyfloats]: https://www.ctan.org/pkg/easyfloats "easyfloats - CTAN"
[endfloat]: https://www.ctan.org/pkg/endfloat "endfloat - CTAN"
[fewerfloatpages]: https://www.ctan.org/pkg/fewerfloatpages "fewerfloatpages - CTAN"
[flafter]: https://www.ctan.org/pkg/flafter "flafter - CTAN"
[float]: https://www.ctan.org/pkg/float "float - CTAN"
[here]: https://www.ctan.org/pkg/here "here - CTAN"
[hvfloat]: https://www.ctan.org/pkg/hvfloat "hvfloat - CTAN"
[keyfloat]: https://www.ctan.org/pkg/keyfloat "keyfloat - CTAN"
[listings]: https://www.ctan.org/pkg/listings "listings - CTAN"
[morefloats]: https://www.ctan.org/pkg/morefloats "morefloats - CTAN"
[nidanfloat]: https://www.ctan.org/pkg/nidanfloat "nidanfloat - CTAN"
[placeins]: https://www.ctan.org/pkg/placeins "placeins - CTAN"
[rotfloat]: https://www.ctan.org/pkg/rotfloat "rotfloat - CTAN"
[stfloats]: https://www.ctan.org/pkg/stfloats "stfloats - CTAN"
[subcaption]: https://www.ctan.org/pkg/subcaption "subcaption - CTAN"
[tcolorbox]: https://www.ctan.org/pkg/tcolorbox "tcolorbox - CTAN"
[wrapfig]: https://www.ctan.org/pkg/wrapfig "wrapfig - CTAN"
[wrapfig2]: https://www.ctan.org/pkg/wrapfig2 "wrapfig2 - CTAN"

## ■ フロートとして扱う

図表などのオブジェクトを “フロートとして扱う” には、floating 環境を利用します。floating 環境は、デフォルトで figure 環境と table 環境があります。
また、floating 環境は環境内の中身を問いません。そのため、table 環境内に図が含まれていても問題ありません。

:::note info
本記事では、figure 環境や table 環境などをまとめて **floating 環境** と呼称します。
:::

ドキュメントが 2 段組となっている場合、floating 環境はカラムのどちらか一方に配置されます。段抜きされたフロートとする場合は floating\* 環境を利用します。

floating 環境内で利用できる `\caption` には、次の 2 つの機能も有しています。

- 相互参照のためのラベル (`\label`)
- リスト作成 (`\listoffigures` etc.)

キャプションに関するカスタマイズは [caption][] パッケージを利用すると簡便です。

## ■ フロートの特徴

フロートの特徴は、次のような点が挙げられます。

- **ページをまたがない**
- **フロートどうしの順序は互いに入れ替わらない**
- **異なる floating 環境は別のフロートとして扱われる**

以上の点が示すように、**フロート内のオブジェクトは本文と切り離されたものとして扱われます**。フロートとして扱う図表などのオブジェクトは本文を補足するものであって、本文に続く形で表現されるものではありません。そのため、フロートとして扱う図表は、基本的にドキュメント内のどこにあっても問題ないものとして扱います。

フロートの配置場所について、LaTeX ではフロートを以下 4 つのいずれかに配置します。（括弧内は対応する配置指定子）
- floating 環境と本文との相対的な場所 (`h` /here)
- ページの上部 (`t` /top)
- ページの下部 (`b` /bottom)
- フロートページ（フロートのみのページ）(`p` /page)

ただし、2 段組における段抜きフロートは、`h`・`b` が利用できません。

このような場所に配置するため、フロートとして扱うオブジェクトは本文内で「下の図を見ると……」のような参照は適しません。フロートは必ずしも参照した本文の直下に配置されるとは限らないためです。
本来の使い方は、相互参照を利用して「図 `\ref{label}` を見ると……」とします。

:::note warn
**フロートとして扱われたオブジェクトは、執筆者の意図した場所に配置することを目的としていない** ことを念頭に置いておく必要があります。

そうでなければ、「LaTeX が勝手に場所を変更してしまい不便だ」と感じてしまいます。これは、フロートの目的をきちんと理解していないことに起因しています。

もしも特定の場所に配置したい場合は、フロートとして扱わないことも検討するべきです。
:::

ただし、フロートが期待した場所からあまりにも離れた場所に配置されることがあることも事実です。本記事では、このような期待した場所に配置されるようになるべく近づける方法を考えます。

## ■ フロート配置アルゴリズムの基本

フロート配置アルゴリズムについて概説します。[^greedy-alg]

[^greedy-alg]: フロート配置アルゴリズムは “greedy” です。アルゴリズムについて詳しくないので言葉のみに留めますが、greedy なアルゴリズムとは「その場での最善の手を選ぶことを繰り返す」性質を持つアルゴリズムです。（[参照][algo-logic]）

[algo-logic]: https://algo-logic.info/greedy/ "貪欲なアルゴリズム（greedy）入門 | アルゴリズムロジック"

:::note info
このアルゴリズムに関する説明は “[How to influence the position of float environments like figure and table in LaTeX? (PDF)][tug-floatalg]” を参照します。[^floatalg]
:::

[^floatalg]: このドキュメントの作成日は 2012 年ですが、現在でも変わりません。このドキュメントの元となった [LaTeX Stack Exchange の回答][q-texstack-float-alg] は内容が現在も更新されているようです。

[tug-floatalg]: https://www.latex-project.org/publications/2014-FMi-TUB-tb111mitt-float-placement.pdf "2014-FMi-TUB-tb111mitt-float-placement.pdf - Articles ordered by topic: Floats"
[q-texstack-float-alg]: https://tex.stackexchange.com/a/39020 "positioning - How to influence the position of float environments like figure and table in LaTeX? - TeX - LaTeX Stack Exchange"

このアルゴリズムは、LaTeX が floating 環境に出会うところから始まります。

floating 環境で指定された配置指定子（デフォルトでは多く `[tbp]` が指定されている）を確かめながら、`h` → `t` → `b` → `p` の順で配置が検討されます。（指定されない指定子はスキップされます）
`!` は指定された配置指定子を優先するために、いくつかのパラメタの制限を無視するように動作します。

誤解してはならないことは、`h` は「配置できるならばココに配置」を意味しており、「絶対にココに配置」を意味していません。`h!` についても同様です。また、`[h]` が指定されたフロートが保留された場合、以降では `[ht]` として処理されます。

このアルゴリズム内で配置場所を決定できない場合、配置が一旦保留されます。フロートの順序は変更されないので、前のフロートが保留されている場合、次のフロートも保留されます。この保留は最大 52 個です。

保留されたフロートはページが改まる度に配置が検討され、配置が決まらなければ継続して保留されます。執筆者側から保留されたフロートを解放することも出来ます。

このフロート配置アルゴリズムは、フロート A とフロート B では別個に行われます。そのため、保留されたそれぞれのフロート A・B の中では順序を替えませんが、近接した特定のフロート A とフロート B の順序は入れ替わる可能性があります。

### ▽ 配置調整のタイミング

前述した [参照ドキュメント][tug-floatalg] の最後 (§ 6.7) でも言及されていますが、**フロートの配置調整はドキュメントの本文を書き終えてから** にしましょう。加筆修正を行っている内に、配置が変わってしまい調整のための労力が無駄になる可能性さえあります。

したがって、執筆中は不都合な場所へのフロートの配置を甘んじて受け入れる必要があります。[^writing-tips]

[^writing-tips]: 執筆中、フロートの配置場所が大きく変更されることにストレスを感じる場合、一旦すべてのフロートを `[p]` に配置させておくと良いかも知れません。

    [float][] パッケージから提供される `\floatplacement` を利用すると、フロートのデフォルト配置指定子を変更することが出来ます。

    あるいは、[endfloat][] パッケージを利用して、ドキュメントの末に配置することも出来ます。

> **§ 6.7 Final tuning advice**
>
> There are many ways to fine-tune the behavior of the float placement algorithm; most of them have been discussed in this article. However, there is one more “tuning” possibility and in fact the biggest of all: changes in your document text.
>
> Therefore, as final advice: do not start manipulating parameters or change placement specifiers or move floats within your document until after you have fully written your text and your document is close to completion. It is a waste of effort and it may even result in inferior placements as your initially provided restrictions may no longer be adequate after a text change.

また、LaTeX のフロート配置アルゴリズムは一度配置が決定すると、そこから立ち戻って再度配置を検討するようなバックトラックを行いません。ドキュメントの先頭から順番に配置していきます。

この性質から分かるように、**配置調整の必要があるフロートは、調整するべき最も初めのフロートから調整しなければなりません**。

### ▽ 保留されたフロートの解放

保留されたフロートは、うまく配置できる場所が見つかるまで保留され続けます。このとき、あまりにも遠い場所にフロートが配置される場合など、執筆者側から保留されたフロートを早い段階で解放したいことがあります。

執筆者が手動で保留されたフロートを解放するには、以下のような方法があります。

|                  コマンド                   | 説明                                                                             |
| :-----------------------------------------: | :------------------------------------------------------------------------------- |
|                `\clearpage`                 | 保留フロートをすべて配置してから改ページ                                         |
| `\afterpage{\clearpage}` <br> ([afterpage][]) | 現在のページを本文で埋めた後、次のページが始まる前に `\clearpage` が挿入される   |
|      `\FloatBarrier` <br> ([placeins][])      | フロートの越えられない壁を形成する（このコマンドの前までにフロートが配置される） |

placeins パッケージは、`section` パッケージオプションから `\section` 毎に `\FloatBarrier` を置くことも出来ます。

```latex
\usepackage[section]{placeins}
```

## ■ 配置される場所をコントロールする

LaTeX におけるフロートは、執筆者の期待しているところに配置されるとは限りません。そのため、しばしば執筆者にとって不都合な場所にフロートが配置される場合があります。

一般的に、フロートは本文内で相互参照した近くにあることが望まれます。そのため、“**floating 環境は本文内で参照 (`\ref`) される段落の前後に挿入すると良い**” とされています。また、フロートは “**本文のどの場所に floating 環境が挿入されているか**” によってある程度はコントロールすることが出来ます。

また当然ですが、配置指定子を調整することでも、配置される場所をコントロールすることが出来ます。デフォルトでは多く `[tbp]` が指定されています。
フロートページへの配置を抑えたい場合は、`[tb!]` に変更するなどの方法を採ることが出来ます。

フロート用のパラメタを調整することでコントロールすることも出来ます。しかしこれらのパラメタ調整は、執筆者にとって思わぬ動作を招く可能性もありオススメ出来ません。この [フロート配置アルゴリズムに関するパラメタは約 20][float-algorithm-parameters] あります。

[latexref-floatPalameter]: http://latexref.xyz/Floats.html#index-float-page "Floats (LaTeX2e unofficial reference manual)"
[float-algorithm-parameters]: https://tex.stackexchange.com/questions/39017/how-to-influence-the-position-of-float-environments-like-figure-and-table-in-lat/39020#39020:~:text=Float%20algorithm%20parameters "positioning - How to influence the position of float environments like figure and table in LaTeX? - TeX - LaTeX Stack Exchange"

この節では、次のケースについて配置場所をコントロールする方法を考えます。

- 次節内にフロートが配置される場合（フロートの配置が遅い）
- 特定の場所への配置を抑制したい場合
- なるべく参照と近い場所に配置したい場合
- 異なるフロートの順序が入れ替わる場合
- 文章途中の「特定のココ」に配置したい場合

以下では、画像内における `\ref` による参照へ意図的に色を付けています。

### ▽ 次節内にフロートが配置される場合

次節内にオブジェクトが配置されている場合、オブジェクトがどの節に属している不明瞭になってしまい、気持ちの良い配置にならないことがあります。

例えば、次のようなテキスト領域の高さ 70% を占めるような図を挿入した場合を考えます。図 example-image-a は節 1 Example A に含まれています。

```latex
% +++
% latex = "lualatex"
% +++
\documentclass{article}
\usepackage{mwe}
\begin{document}

\section{Example A}

\lipsum[1-4]
Figure~\ref{fig:example-image-a}

\begin{figure}
  \centering
  \includegraphics[ height = 0.7\textheight, width = 0.8\linewidth ]{example-image-a}
  \caption{Example A}
  \label{fig:example-image-a}
\end{figure}

\section{Example B}

\lipsum[1-4]

\end{document}
```

これをタイプセットすると、次のように図 example-image-a がドキュメントの最後に出力されてしまっています。これでは、図 example-image-a は節 1 で参照しているにも関わらず、あたかも節 2 で参照しているように感じてしまいます。

|            1 ページ目             |            2 ページ目             |            3 ページ目             |
| :-------------------------------: | :-------------------------------: | :-------------------------------: |
| ![high-image-1][img-height-page1] | ![high-image-2][img-height-page2] | ![high-image-3][img-height-page3] |

[img-height-page1]: https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590705/5254fc00-2010-49f5-8faa-3c0e4eea7c19.png "§ 1 と § 2 が連続して出力されているページ"
[img-height-page2]: https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590705/5ea82b1f-6d17-ce7e-e8c8-8dbe4b99ff7f.png "§ 1 内で利用している図のみのページ"
[img-height-page3]: https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590705/8badd55b-9748-d473-093b-4109c6cc3c0c.png "§ 2 が出力されているページ"

これを回避するには、以下の 2 つの方法があります。

- `\section{Example B}` の前で `\clearpage`
- `\usepackage[section]{placeins}` を利用する

上の例では、この 2 つの方法のどちらを利用しても、以下に示す同じような結果を得ました。

|           1 ページ目           |           2 ページ目           |           3 ページ目           |
| :----------------------------: | :----------------------------: | :----------------------------: |
| ![high-image-1][img-sep-page1] | ![high-image-2][img-sep-page2] | ![high-image-3][img-sep-page3] |

[img-sep-page1]: https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590705/cde856f2-62de-11e9-1c6e-0e4a382883ac.png "§ 1 のみが出力されているページ"
[img-sep-page2]: https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590705/80aa5624-677a-fe09-4c2c-72c9da886185.png "§ 1 内で利用している図のみのページ"
[img-sep-page3]: https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590705/2e56d579-7969-ab17-6a31-fd8d8dd91512.png "§ 2 のみが出力されているページ"

### ▽ 特定の場所への配置を抑制したい場合

1 ページ目や章の始まるページでは、上部あるいは下部にフロートを配置したくない場合があります。そのような場合、`\suppressfloats` を対象にしたい floating 環境の前に置くことで、フロートの配置を避けることが出来ます。（ただし、配置指定子に `!` が含まれる場合、配置指定子が優先され `\suppressfloats` は無視されます）

|       コマンド       | 説明                     |
| :------------------: | :----------------------- |
|  `\suppressfloats`   | このページへの配置を抑制 |
| `\suppressfloats[t]` | 上部への配置を抑制       |
| `\suppressfloats[b]` | 下部への配置を抑制       |

`\suppressfloats` のオプション引数は `t`・`b` しか採りません。

次のような例を考えると分かりやすいです。

```latex
% +++
% latex = "lualatex"
% +++
\documentclass{article}
\usepackage{mwe}
\begin{document}

\section{Example A}

\lipsum[1-3]

% \suppressfloats[t]
%% floating 環境よりも前に置く

\begin{figure}[tbp]
  \centering
  \includegraphics[width=0.4\linewidth]{example-image-a}
  \caption{Example A}
  \label{fig:example-image-a}
\end{figure}

\end{document}
```

この例では、節 1 Example A よりも前に図 example-image-a が出力されてしまいます。今回、これを避けようと考えています。すなわち、上部に配置させずに下部または 1 ページに出力させたいと考えています。

以下に、`\suppressfloats[t]` の有無による違いを表にしました。

|       `\suppressfloats[t]` 無し        |       `\suppressfloats[t]` 有り        |
| :------------------------------------: | :------------------------------------: |
| ![suppressfloats-noactive][img-active] | ![suppressfloats-active][img-noactive] |

[img-noactive]: https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590705/37bfe931-aa52-4cb2-0014-ba4a94c75545.png "`\suppressfloats[t]` によって図が下部に出力されているページ"
[img-active]: https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590705/412b803b-7ae8-8270-2a60-7e7b9a2f6e34.png "§ 1 見出しより前に図が出力されているページ"

`\suppressfloats[t]` 有りでは、期待していた上部への配置を避けることが出来ました。

実際この例では、`\begin{figure}[bp]` としても同じ結果を得ます。意味としては同じものになっているようです。

これは単に floating 環境の配置指定子を抑制しているだけですが、加筆修正するに当たって、直接、配置指定子を変更する必要が無い点において有意義であることを強調しておきます。

### ▽ なるべく参照と近い場所に配置したい場合

次のようなドキュメントを作成した場合、フロートは `[tb]` では末ページのフロートページ、`[H]` では 2 ページ目の途中に Here として配置されます。

```latex
% +++
% latex = "lualatex"
% +++
\documentclass{article}
\usepackage{mwe}
\usepackage{float}
\begin{document}

\section{Example A}

\lipsum[1-3]
Figure~\ref{fig:example-image-a}

\begin{figure}[tb]
% \begin{figure}[H]
  \centering
  \includegraphics[ width = 0.8\linewidth, height = 0.7\textheight ]{example-image-a}
  \caption{Example image A}
  \label{fig:example-imaeg-a}
\end{figure}

\lipsum[4-9]

\end{document}
```

|         |            1 ページ目             |            2 ページ目             |            3 ページ目             |
| :-----: | :-------------------------------: | :-------------------------------: | :-------------------------------: |
| `[tbp]` | ![tbp-float-page1][img-far-page1] | ![tbp-float-page2][img-far-page2] | ![tbp-float-page3][img-far-page3] |
|  `[H]`  | ![H-float-page1][img-Here-page1]  | ![H-float-page2][img-Here-page2]  | ![H-float-page3][img-Here-page3]  |

[img-far-page1]: https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590705/38e2501c-c486-f473-4916-bf0be5be39fc.png "`[tb]` を指定しているフロートの配置 - ページ 1"
[img-far-page2]: https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590705/96068b4e-c6ee-7fa4-cb84-e7d422984fda.png "`[tb]` を指定しているフロートの配置 - ページ 2"
[img-far-page3]: https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590705/9242526c-213e-8d4c-e8d1-e070c751c35f.png "`[tb]` を指定しているフロートの配置 - ページ 3"

[img-Here-page1]: https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590705/1e2069a0-bd51-049f-6b4d-4a73c934c3bd.png "`\afterpage{[H]}` フロートの配置 - ページ 1"
[img-Here-page2]: https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590705/b0bd8486-574d-c4be-1ba3-d1feef5df1c1.png "`\afterpage{[H]}` フロートの配置 - ページ 2"
[img-Here-page3]: https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590705/4413f597-6b3a-8887-a26c-a703279c32a0.png "`\afterpage{[H]}` フロートの配置 - ページ 3"

Here ではなく、単に参照された位置と近い場所にフロートを配置したい場合、[afterpage][] パッケージの `\afterpage` と [float][] パッケージの `[H]` を利用することで実現できます。
ただし、配置場所は `t` に相当する場所に固定されてしまいます。

```latex
% +++
% latex = "lualatex"
% +++
\documentclass{article}
\usepackage{mwe}
\usepackage{afterpage}
\usepackage{float}
\begin{document}

\section{Example A}

\lipsum[1-3]

\afterpage{
  \begin{figure}[H]
    \centering
    \includegraphics[ width = 0.8\linewidth, height = 0.7\textheight ]{example-image-a}
    \caption{Example image A}
  \end{figure}
}

\lipsum[4-9]

\end{document}
```

|                   1 ページ目                    |                   2 ページ目                    |                   3 ページ目                    |
| :---------------------------------------------: | :---------------------------------------------: | :---------------------------------------------: |
| ![afterpage-H-float-page1][img-afterpage-page1] | ![afterpage-H-float-page2][img-afterpage-page2] | ![afterpage-H-float-page3][img-afterpage-page3] |

[img-afterpage-page1]: https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590705/aebd5f89-decb-bda1-7945-63d65b549c3e.png "`[H]` を指定しているフロートの配置 - ページ 1"
[img-afterpage-page2]: https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590705/da53522e-ddea-f580-af88-dc9f27045f27.png "`[H]` を指定しているフロートの配置 - ページ 2"
[img-afterpage-page3]: https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590705/324c76a9-fe61-481d-fe13-5648293ae201.png "`[H]` を指定しているフロートの配置 - ページ 3"

### ▽ 異なるフロートの順序が入れ替わる場合

異なる 2 種以上のフロートがある場合、これらの順序は入れ替わる可能性があります。

例えば、次のような figure 環境と table 環境が連続するようなドキュメントを考えます。本文内では “図 → 表” の順で参照しているものとします。（“A → B” の順になってほしい）

```latex
% +++
% latex = "lualatex"
% +++
\documentclass{article}
\usepackage{mwe}
\begin{document}

\section{Example A}

\lipsum[1-6]

\begin{figure}
  \centering
  \includegraphics[ height = 0.7\textheight, width = 0.8\linewidth ]{example-image-a}
  \caption{Example figure}
\end{figure}

\begin{table}
  \centering
  \includegraphics[ height = 0.3\textheight, width = 0.8\linewidth ]{example-image-b}
  \caption{Example table}
\end{table}

\lipsum[1-7]

\end{document}
```

<!--
|                     1                     |                     2                     |                     3                     |                     4                     |
| :---------------------------------------: | :---------------------------------------: | :---------------------------------------: | :---------------------------------------: |
| ![reverse-float][img-reverse-float-page1] | ![reverse-float][img-reverse-float-page2] | ![reverse-float][img-reverse-float-page3] | ![reverse-float][img-reverse-float-page4] |
-->

|                2 ページ目                 |                3 ページ目                 |
| :---------------------------------------: | :---------------------------------------: |
| ![reverse-float][img-reverse-float-page2] | ![reverse-float][img-reverse-float-page3] |

[img-reverse-float-page1]: https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590705/572a77d4-cb1f-925d-b3bb-a01e0b7908cb.png "異なるフロートの順序が入れ替っている - page1"
[img-reverse-float-page2]: https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590705/b5c0085e-8af7-7805-5f03-3d9b3fd73d7c.png "異なるフロートの順序が入れ替っている - page2"
[img-reverse-float-page3]: https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590705/0efcd41d-2ceb-29a6-03df-f0ad5906d15e.png "異なるフロートの順序が入れ替っている - page3"
[img-reverse-float-page4]: https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590705/d8678319-1630-c491-6416-c700dff4747c.png "異なるフロートの順序が入れ替っている - page4"

すると、TeX ソース内では “図 → 表” の順で floating 環境を書いているにも関わらず、生成された PDF では “表 → 図” の順でフロートが表示されています。（1・4 ページ目はテキストのみのページです）

フロートの特徴を思えば、この順序の入れ替わりを気にするべきではありませんが、本文中で参照の順序が “図 → 表” の順としている場合には気になります。

この順序の入れ替わりを無くすためには、[placeins][] パッケージの `\FloatBarrier` を利用します。ここでは、2 種のフロートの順序が入れ替わらないようにするためだけなので、改ページをしてしまう `\clearpage` は適しません。

また、今回は図がフロートページになっているため、`[tbp]` を `[tb!]` に変更しました。

```latex
% +++
% latex = "lualatex"
% +++
\documentclass{article}
\usepackage{mwe}
\usepackage{placeins}
\begin{document}

\section{Example A}

\lipsum[1-6]

\begin{figure}[tb!]
  \centering
  \includegraphics[ height = 0.7\textheight, width = 0.8\linewidth ]{example-image-a}
  \caption{Example figure}
\end{figure}
\FloatBarrier

\begin{table}
  \centering
  \includegraphics[ height = 0.3\textheight, width = 0.8\linewidth ]{example-image-b}
  \caption{Example table}
\end{table}

\lipsum[1-7]

\end{document}
```

<!--
|                       1                       |                       2                       |                       3                       |                       4                       |
| :-------------------------------------------: | :-------------------------------------------: | :-------------------------------------------: | :-------------------------------------------: |
| ![reverse-float][img-reverse-float-fix-page1] | ![reverse-float][img-reverse-float-fix-page2] | ![reverse-float][img-reverse-float-fix-page3] | ![reverse-float][img-reverse-float-fix-page4] |
-->

|                  2 ページ目                   |                  3 ページ目                   |
| :-------------------------------------------: | :-------------------------------------------: |
| ![reverse-float][img-reverse-float-fix-page2] | ![reverse-float][img-reverse-float-fix-page3] |

[img-reverse-float-fix-page1]: https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590705/2bb31c3a-dfe9-997e-a2b8-899ce99f6b26.png "異なるフロートの順序が入れ替っている - page1"
[img-reverse-float-fix-page2]: https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590705/6a2c9a79-b508-8c8d-dfd2-13466c8f152a.png "異なるフロートの順序が入れ替っている - page2"
[img-reverse-float-fix-page3]: https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590705/4fb0b2ad-ec37-60e0-8ac0-6f834faca25f.png "異なるフロートの順序が入れ替っている - page3"
[img-reverse-float-fix-page4]: https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590705/25a9d3b4-7e72-a14f-d7f7-9179f8622ff9.png "異なるフロートの順序が入れ替っている - page4"

この問題としているフロートよりも前のフロートが保留されている場合、`\FloatBarrier` の前でこれらの保留フロートが解放されます。そのため、“図 → 表” の参照をしているパラグラフの後に直接関係のないフロートが配置される可能性があります。

### ▽ 文章途中の「特定のココ」に配置したい場合

フロートとして扱うオブジェクトは「執筆者の意図する場所に配置することを目的としない」と説明していましたが、積極的に意図する場所に配置させる方法があります。

次の 2 つの方法があります。

- `[H]` 指定子の利用
- フロートとして扱わずにキャプションだけ与える

:::note warn
これらの方法は **フロートの順序が入れ替わる可能性** があります。

また、**執筆者自身で図表などのオブジェクトがはみ出さないよう上手に調整する必要** があります。
:::

<details>
<summary>フロートの順序が入れ替わる簡単な例（折りたたみ）</summary>

```latex
% +++
% latex = "lualatex"
% +++
\documentclass{article}
\usepackage{mwe}
\usepackage{float}
\newcommand{\examplefigure}[2]{ \begin{figure}[#1] \centering \includegraphics[ height = #2\textheight, width = 0.8\linewidth ]{example-image-a} \caption{\texttt{#1}} \end{figure} }
%% #1: placement specifiers
%% #2: ratio of `\textheight'
\begin{document}

\lipsum

\examplefigure{tbp}{0.6}
\examplefigure{tbp}{0.4}

\examplefigure{H}{0.4}

\lipsum

\end{document}
```

</details>

#### ● `[H]` 指定子の利用

デフォルトでは、`[h!]` を利用することで「配置できるならばココ」に配置することが出来ます。ただし、これは必ずしもココに配置されるとは限りません。

これよりも「絶対にココ」に配置したい場合は、[float][] パッケージの `[H]` を利用します。（[here パッケージではない][sec-here] ことに注意してください）

[sec-here]: #お使いの-here-パッケージは本当に-here-パッケージですか "§ お使いの here パッケージは本当に here パッケージですか"

ただし、`[H]` は単独で利用することを要請します。`[Htbp]` のような使い方は出来ません。

#### ● フロートとして扱わずにキャプションだけ与える

オブジェクトをフロートとして扱わない選択も出来ます。そもそも、フロートは特定の場所に配置する目的には向きません。オブジェクトがはみ出すなどの注意が必要ですが、これさえ自力でどうにかしてしまえばフロートとして扱わなくても問題ありません。

figure・table 環境を利用せずに直接 `\includegraphics` や `\begin{tabular}` としてしまえば良いです。

非フロートのオブジェクトにキャプションを付与したい場合には、[caption][] パッケージの `\captionof` を利用します。`\captionof` は 1 つ目の引数にフロートとしての種類、2 つ目の引数にキャプションを採ります。

```latex
{
  \centering
  \includegraphics{image.pdf}
  \captionof{figure}{Incredible image!}
}
```

## ■ フロートページを減らしたい

保留されたフロートが新たなページで配置される際に、このフロートはフロートページ（フロートのみのページ）を形成する傾向があります。

これは、新たなページ内でフロートオブジェクトが 50% (`\floatpagefraction`) 以上を占めた場合、フロートページとしてうまく構成されていると判断されるためです。そのため、最大でおよそ半分空のページが形成されてしまい、見栄えの良くないドキュメントとなってしまいます。

このような場合には、[fewerfloatpages][] パッケージを利用します。このパッケージはフロートの配置アルゴリズムを拡張することで、次の目的を果たします。
- フロートページをなるべく減らす
- floating 環境がある場所からなるべく近い場所にフロートを配置する

:::note info
以下では、パッケージが提供するパラメタやパッケージオプションを紹介しますが、パッケージを読み込むだけでもかなり改善されることがあります。
:::

このパッケージから、3 つのパラメタが提供されています。これらのパラメタを変更することによって、保留されているフロートがフロートページを形成する傾向を解消します。（“:” 右はデフォルト値）

- **`floatpagedeferlimit`**: `3` (`totalnumber`)

    フロートページを形成する最大保留フロート数

    この値以上のフロートが保留されている場合、フロートページの形成をなるべく抑制する

    `0` を採る場合、機能が停止する

- **`floatpagekeeplimit`**: `3`

    フロートページに含まれる最大フロート数（フロートページを複数に分割しないようにする）

    `floatpagekeeplimit` ≤ `floatpagedeferlimit` のとき、意味を成します

- **`\floatpagekeepfraction`**: `0.2` (`\textfraction`)

    フロートがページを満たしているかどうかの基準

    フロートで占められたページの残りが、
    - この値以上の場合、本文が含められる
    - この値以下の場合、フロートページとして形成される

さらに、3 つのパッケージオプションがあります。

|        オプション         | 説明                                          |
| :-----------------------: | :-------------------------------------------- |
| `checktb` <br> デフォルト | 技術的に配置不可能な配置指定子を削除する      |
|         `addbang`         | すべての floating 環境に自動的に `!` を与える |
|         `nocheck`         | 配置指定子を調整しない                        |

また、`trace` オプションを有効にすると、フロートが配置されるまでの様子がログファイルに記載されます。

<details>
<summary>fewerfloatpages でフロートの場所が変わる簡単な例（折りたたみ）</summary>

ダミーテキストと 5 つのフロートを含んだドキュメントです。

fewerfloatpages から提供されるパラメタやパッケージオプションを変更することで、具体的な挙動を確認することが出来ます。

```latex
% +++
% latex = "lualatex"
% +++
\documentclass{article}
\usepackage{mwe}
\usepackage[
    checktb
    % addbang
    % nocheck
    ,trace
  ]{fewerfloatpages}
% \setcounter{floatpagedeferlimit}{3}
% \setcounter{floatpagekeeplimit}{3}
% \renewcommand{\floatpagekeepfraction}{0.2}
\newcommand{\examplefigure}[2]{ \begin{figure}[#1] \centering \includegraphics[ height = #2\textheight, width = 0.8\linewidth ]{example-image-a} \caption{\texttt{#1}} \end{figure} }
%% #1: placement specifiers
%% #2: ratio of `\textheight'
\begin{document}

\section{Example A}

\lipsum
\examplefigure{tbp}{0.6}
\lipsum
\examplefigure{tbp}{0.6}
\lipsum
\examplefigure{tbp}{0.6}
\lipsum
\examplefigure{tbp}{0.6}
\lipsum
\examplefigure{tbp}{0.6}
\lipsum

\end{document}
```

</details>

:::note warn
float パッケージの `[H]` や caption パッケージの `\captionof` と fewerfloatpages パッケージを併用すると、簡単にフロートの順序が入れ替わる可能性があります。
:::

<details>
<summary><code>[H]</code> と fewerfloatpages を組み合わせる例（折りたたみ）</summary>

fewerfloatpages パッケージが読み込まれていると、フロートの順序が入れ替わります。

```latex
% +++
% latex = "lualatex"
% +++
\documentclass{article}
\usepackage{mwe}
\usepackage{float}
\usepackage{fewerfloatpages}
\newcommand{\examplefigure}[2]{ \begin{figure}[#1] \centering \includegraphics[ height = #2\textheight, width = 0.8\linewidth ]{example-image-a} \caption{\texttt{#1}} \end{figure} }
%% #1: placement specifiers
%% #2: ratio of `\textheight'
\begin{document}

\lipsum

\examplefigure{tbp}{0.6}
\examplefigure{tbp}{0.4}

\lipsum[1-3]

\examplefigure{H}{0.4}
% {
%   \centering
%   \includegraphics[ height = 0.4\textheight, width = 0.8\linewidth ]{example-image-b}
%   \captionof{figure}{\texttt{\textbackslash{}captionof}}
% }

\lipsum

\end{document}
```

</details>

## ■ もっとフロート

フロートに関するパッケージをいくつか挙げておきます。

- 新しい floating 環境を作成したい
    - [float][]
    - [algorithm][]
- `float` オプション
    - [listings][]
    - [tcolorbox][]
- フロートの周囲にテキストを周り込ませたい
    - [wrapfig][]
    - [wrapfig2][]
- 2 段組で段抜きフロートをページ下部に配置する
    - [nidanfloat][]
    - [stfloats][]
- 複数のフロートを横に並べたい
    - [subcaption][]
- フロートを回転させたい
    - [rotfloat][]
- フロートを節末にまとめたい
    - [endfloat][]
    - flafter
- フロートを key-value 形式で利用する
    - [keyfloat][]
    - [easyfloats][]
    - [hvfloat][]

# 参考

- [Floats (LaTeX2e unofficial reference manual)](http://latexref.xyz/Floats.html)
- [Articles ordered by topic: Floats](https://www.latex-project.org/publications/indexbytopic/2e-floats/)
- [positioning - How to influence the position of float environments like figure and table in LaTeX? - TeX - LaTeX Stack Exchange](https://tex.stackexchange.com/questions/39017/how-to-influence-the-position-of-float-environments-like-figure-and-table-in-lat)
- [How can I get my table or figure to stay where they are, instead of going to the next page? - Overleaf, Online LaTeX Editor](https://ja.overleaf.com/learn/latex/Questions/How_can_I_get_my_table_or_figure_to_stay_where_they_are%2C_instead_of_going_to_the_next_page?)

# 余談

LaTeX におけるフロートの配置は、執筆者にとって一見不規則な動作に思えます。しかし、ある程度はコントロールすることが出来ます。コントロールする術をいくつか知っておくと、フロートに対する心理的ハードルが幾分か下がるでしょう。

一方で、LaTeX では MS Word における「ページ上で位置を固定する」ようなフロートの扱いをすることは出来ません。
この点に関しては、後に開発されることを祈りましょう。

## フロートに関するエラー

フロートを処理する際に、同時に保留できる個数は制限されています。そのため、次のようなエラーが発行されることがあります。

```log
Too many unprocessed floats.
```

これを受けて、[morefloats][] パッケージが開発されました。また、2015 年 1 月には `\extrafloats{N}` が提供され、この当時のデフォルト 18 個に加えて N 個の追加が出来るようになりました。

しかし、同年 10 月には同時に保留できる最大個数が 52 個になったため、実質的に個数の制限によるエラーは生じないものとなったようです。

> **§ More Floats and Inserts**
>
> If ε-TeX is available, the number of registers allocated in the format to hold floats such as figures is increased from 18 to 52.
>
> The extended allocation system introduced in 2015/01/01 means that in most cases it is no longer necessary to load the `etex` package. Many classes and packages that previously loaded this package no longer do so. Unfortunately in some circumstances where a package or class previously used the etex `\reserveinserts` command, it is possible for a document that previously worked to generate an error “no room for a new insert”. In practice this error can always be avoided by declaring inserts earlier, before the registers below 256 are all allocated. However, it is better not to require packages to be re-ordered and in some cases the re-ordering is complicated due to delayed allocations in `\AtBeginDocument`.
>
> In this release, a new implementation of `\newinsert` is used which allocates inserts from the previously allocated float lists once the classical register allocation has run out. This allows an extra 52 (or in LuaTeX, 64 thousand) insert allocations which is more than enough for practical documents (by default, LaTeX only uses two insert allocations).
>
> --- [LaTeX News][latex-news] - Issue 23, October 2015 (2015-10-01)

[latex-news]: https://ctan.math.utah.edu/ctan/tex-archive/macros/latex-dev/base/ltnews.pdf "LaTeX News (PDF)"

## お使いの here パッケージは本当に here パッケージですか

`[H]` 指定子を利用するために [here][] パッケージを利用する人は少なくないでしょう。しかし、here パッケージにはちょっとした問題があります。

次のように here パッケージを読み込ませたファイルに `\listfiles` を含めてタイプセットしてみましょう。（`\lisetfiles` は利用しているパッケージ等をログファイルに一覧化します）

```latex
% +++
% latex = "pdflatex"
% +++
\documentclass{article}
\usepackage{here}
\listfiles
\begin{document}

Hello, \LaTeX{}!!

\end{document}
```

すると、このファイルをタイプセットする際に読み込まれたパッケージ等のログを以下のような一覧として取得することが出来ます。

```log
 *File List*
 article.cls    2022/07/02 v1.4n Standard LaTeX document class
  size10.clo    2022/07/02 v1.4n Standard LaTeX file (size option)
    here.sty
   float.sty    2001/11/08 v1.3d Float enhancements (AL)
l3backend-pdftex.def    2023-03-30 L3 backend support: PDF output (pdfTeX)
 ***********
```

一覧を見ると、どうやら <samp>.sty</samp> ファイルは here.sty と float.sty が読み込まれています。もとのドキュメントでは、`\usepacakge{here}` しか利用していないのに、float パッケージも利用していることになっています。どういうことでしょうか。

次に、[here パッケージ内][ctanmirrors-here] を確認してみましょう。すると、次の 1 行だけが実装されています。

[ctanmirrors-here]: http://mirrors.ctan.org/macros/latex/contrib/here/here.sty "here.sty - CTAN"

```latex
\RequirePackage{float}
```

これは、[float][] パッケージを呼び出しています。したがって、here パッケージを使っていると思っていたものは float パッケージでした。

here パッケージの README を確認すると、here パッケージは撤回され float パッケージに引き継がれていることが記載されています。（here パッケージは後方互換のために残されている）

> The original here.sty by David Carlisle was withdrawn many years ago. The `[H]` modifier is now implemented in float.sty, which this here.sty simply reads. Another option is to use a float specifier `[!ht]`, which usually has the same effect, and keeps floats in the right order. The present trivial here.sty merely allows old documents to keep running.
>
> --- Karl Berry, November 2009.

これは 2009 年 11 月の出来事です。令和になった今でも here パッケージとして使い続ける意味はあまりないでしょう。きちんと float パッケージを使いましょう。