Edited at

Beamer columns 環境で画像を配置するベストな方法

More than 3 years have passed since last update.

この記事では,LaTeX Beamer で画像をいい感じの位置に置く方法,特に columns 環境を使う方法を扱います.


§.0. ことの始まり

後輩氏「Beamer で画像挿入うまくいかないんやで.コレ見てやってみたんやで.」

私氏「誰やこんなクソみたいなコード書いたやつは.あ,私やんけ.」

Google氏「『Beamer 画像』で上の方に出しといてあげたやで.」

私氏「マジかよ勘弁しちくり〜〜〜」

そういうわけで,3 年前のアレなコード1に引導を渡すべく,Beamer で画像を意図通り配置するための本当のベストプラクティスについて考察していきたいと思います.


§.1. はじめに

本稿のサンプルは,執筆時にいくつかの環境 (TeX Live 2015 / Mac OS X, TeX Live 2014 / Debian Jessie, etc.) にてタイプセットできることを確認しています.以下に,サンプル用のコマンド定義を含むプリアンブルを示します.


beamer-column.tex

\PassOptionsToClass{hiresbb}{graphicx}

\documentclass[dvipdfmx]{beamer}
\usepackage{graphicx}
\newcommand{\thickhrulefill}{\leavevmode\leaders\hrule depth-1.2pt height 3.2pt\hfill\kern0pt}
\newcommand{\indicatewidth}[1]{\thickhrulefill{#1}\thickhrulefill}
\begin{document}
...
\end{document}

上のサンプルは platex + dvipdfmx を前提としていますが,本稿の内容は pdflatex 等の場合でも全く同様です(オプションのドライバ等は適宜書き換えてください).本稿には,スクリーンショット以外には必要最小限のコードしか載せていません.スクリーンショットを再現するためのサンプルコード全文は Gist を参照してください.

画像の挿入に関する一般的なトラブルシューティングに関しては本稿では扱っていません(何かお困りの場合はまず日本人のための LaTeX タブー集 ~画像読込編~を読むことを強くお薦めします).


§.2. オマジナイに頼ってはいけない

3 年前の記事「Beamer 2-column スライドで片方に画像を表示」で掲載したイディオムは,以下に挙げる理由により使ってはいけません


  • 一度はうまく行くように見えますが,このイディオム二度使用すると,意図通りに表示されなくなります.


    • 特に,Beamer theme の他の要素に破壊的な影響を与える可能性があり,たいへん危険といえます.




  • \pgfputat および \pgfxy は古いバージョンとの互換性のために残されている命令ですので,標準で定義されているとは限りません.



    • \usepackage{pgf} すれば互換性のための命令も一応は定義されます2

    • 最新のマニュアル "TikZ & PGF Manual for Version 3.0.1a" にもこれらの命令に関する記述はありません (Cf. texdoc pgf).Undocumented な命令に頼るべきではありません.




§.3. columns 環境の正しい使い方

Beamer で画像を配置する方法で困ったときに,最初に考慮すべき方法は columns 環境を使うことです.columns は由緒正しい (?) Beamer の環境であり,Beamer マニュアルにも


Usually, place graphics to the left of the text. (Use the columns environment.) In a left-to-right reading culture, we look at the left first.


と書かれています3(強調は筆者).しかし,この方法は公式推奨の癖に割と罠だらけです(ある意味前述の方法もそうですが).実は,columns 環境を使って画像を思い通りの位置に置けないとき,その原因は画像のほうではなく columns 環境のほうにあることが多いです4.ということでまずは columns 環境について詳しくみていきます.


column(s) 環境の width の指定について

次の例をみてください.

\begin{frame}

\begin{block}{columns[t], 0.5:0.5}
\fbox{
\begin{columns}[t]
\begin{column}{0.5\linewidth}\indicatewidth{left column}\end{column}
\begin{column}{0.5\linewidth}\indicatewidth{right column}\end{column}
\end{columns}
}
\par\indicatewidth{outside}
\end{block}
\end{frame}

\indicatewidth{} は上でサンプル用に定義した,幅めいっぱいに「横線」を引く命令です.これをタイプセットすると図のようになります.地の文の行幅に対して columns の幅が広く,またそれぞれの column がちょっと外側にはみ出ている様子が分かります.

スクリーンショット 2016-02-13 21.27.00.png

そこで [onlytextwidth] オプションを指定したところが次の図です.このオプションは [totalwidth=\textwidth] と同じ効果をもち,columns 領域幅をちょうど一行分だけとるということです.中に収まりましたが今度は中央がくっつきました.

スクリーンショット 2016-02-13 21.27.51.png

中央がくっついているのは,幅の合計が 1 にならないようにすると解消されます.columns 環境はマージンのことまでよしなにはしてくれませんから,合計をぴったり 1 にするよりも,適当にバッファを持たせる方が見た目よく振舞うことが多いです.右側余白が小さい問題も,totalwidth を適当に 1 より小さい幅を指定するのが簡単です(やはりマージンのことまでよしなにはしてくれません).

スクリーンショット 2016-02-13 21.28.48.png

まとめると,columnstotalwidth および各 column の幅は,ぴったりの値より小さめに設定するのが良いです.

参考に,3 段組の場合も掲載しておきます.

スクリーンショット 2016-02-13 21.31.01.png


\includegraphics とアラインメント

さて,画像の話に移ります.実は,\includegraphics と組み合わせると,また新たな問題が発生します.次のコードとそのタイプセット結果をみてください.

\begin{frame}{悪い例}

\begin{block}{[t], 0.8:0.2}
\fbox{
\begin{columns}[t]
\begin{column}{0.8\linewidth}
some paragraph\par some paragraph
\par\indicatewidth{left}
\end{column}
\begin{column}{0.2\linewidth}
\fbox{\includegraphics[width=1.0\linewidth]{pic/0inN.png}}
\par\indicatewidth{right}
\end{column}
\end{columns}
}
\end{block}
\end{frame}

スクリーンショット 2016-02-13 21.32.41.png

あらまーひどい! まぁちょっと考えれば分かることなんですが,これはアラインメントオプション [t] によるものです(さっきから明示的に指定していましたがこれは columns 環境のデフォルトです).[t] は各カラムの一行目のベースラインを上揃えするものですから,各カラムの最初の行の高さが違えばこのとおり!

スクリーンショット 2016-02-13 21.34.02.png

columns の幅指定に余裕をもたせて,横にはみ出る問題も解消してあります.この上揃いが \includegraphicscolumns を組み合わせたときの不細工なレイアウトの正体です.したがって,アラインメントオプションを適切に指定することで解消できます.それぞれのオプションの意味は以下のとおりです.



  • [t]: 上揃え(一行目ベースライン)


  • [T]: 上揃え(一行目上端)


  • [c]: 中央揃え


  • [b]: 下揃え

スクリーンショット 2016-02-13 21.35.49.png

[T] を使うことでベースラインではなく上端基準で揃えられるので,画像を組み合わせる場合はこのオプションを使うといいでしょう5.また,columns ではなく個別の column にアラインメントを指定することで,途中でアラインメントを変更することもできます.上の [T] の例では,文章・画像ともに少し上にはみ出ていますが,[t][T] を使い分けることでいい感じになります.

スクリーンショット 2016-02-13 21.36.52.png

左の column には [t] を,右の column には [T] を,それぞれ指定しています.ただし,場合によると思いますが,[c][b] とは組み合わせない方がいいでしょう.


figure 環境も使う場合

figure 環境を使いたい人もいると思うので,一応言及しておきます.まずは例によって悪い例から.

\begin{frame}{figure環境を使った悪い例}

\begin{block}{[t], 0.8:0.2, figure}
\fbox{
\begin{columns}[t]
\begin{column}{0.8\linewidth}
some paragraph\par some paragraph
\par\indicatewidth{left}
\end{column}
\begin{column}{0.2\linewidth}
\begin{figure}
\fbox{\includegraphics[width=1.0\linewidth]{pic/0inN.png}}
\end{figure}
\par\indicatewidth{right}
\end{column}
\end{columns}
}
\end{block}
\end{frame}

スクリーンショット 2016-02-13 21.39.54.png

あ,ハイ,今度はそうなるんですね.

分かりづらいですが,figure 環境の作る余白の分だけ下がって上揃えされています.そもそも Beamer での figure は floating box ではなくただ center 環境をラップしたものです.この空白が嫌であれば,figure 環境ではなく \centering を使うべきです.\caption をつけたいなどの理由があってかつどうしても上に詰めたければ,段落一行分くらいのネガティブスペースを入れるしかないでしょう.

スクリーンショット 2016-02-13 21.41.07.png


[こらむ]: \ナントカwidth の違い

結論を言うと,\ナントカwidth の違いはあまりありません.

幅の長さを表す命令として \hsize, \textwidth, \columnwidth, \linewidth などがありますが,いずれも column(s) 環境の幅を指定する際には同じ値を持つハズです.したがって,どれを使っても差し支えありません.ちなみに \columnwidth は文書の段組 (e.g. \documentclass[twocolumn]{article}) に応じた値をもつものであり,column(s) 環境とは直接関係ありません.よって \columnwidth を使って幅を指定するのは混乱の元ですから,やめたほうがいいでしょう.

一応,他に違いが出る状況として,itemize 内で columns を用いたときなどが考えられますが,まぁナイでしょう.詳しいことはこちら Difference between \textwidth, \linewidth and \hsize の質問への回答が参考になります.

2016-03-01追記: 上の書き方だと,さも \columnwidth の値はその文書内で不変であるかのように読め,そのため columns 環境をネストしているとき(あるいはより一般に minipage 環境にいるときなど)には違いが出るんじゃないかと思われそうですが,実際にはその場合ですら同じ値を持ちます.つまり,minipage は常に一段組みであり結局のところ \textwidth\columnwidth は同じ値になります.ちなみに二段組み文書のトップレベルならばちゃんと \textwidth\columnwidth の約 2 倍の値を持ちます.


§.4. 最後の手段

一応,最終手段として,絶対座標指定して好きな位置に置く方法があります.それはもう割と面倒ですし,本稿の趣旨からは外れてしまいますので,Beamer マニュアルの文章を引用するにとどめます.


12.8 Positioning Text and Graphics Absolutely

Normally, beamer uses TeX's normal typesetting mechanism to position text and graphics on the page. In certain situation you may instead wish a certain text or graphic to appear at a page position that is specified absolutely. This means that the position is specified relative to the upper left corner of the slide.

The package textpos provides several commands for positioning text absolutely and it works together with beamer. When using this package, you will typically have to specify the options overlay and perhaps absolute. For details on how to use the package, please see its documentation.


(Cf. texdoc beamer; 強調は筆者)

意訳:texdoc textpos とかを読んでね.

あと wrapfig を使う方法もありますが,この方法はあまり Beamer 向きではないように私は思います(これも色々落とし穴だらけだし).


§.5. ベストプラクティス

以上のことを踏まえた二段組みサンプルです.チョット余裕を持たせるのがそれはそれは面倒ですので,\mytotalwidth\mycolumnwidth を新たに定義しています(5mm ではなくそれらしいマージンの値を引っ張ってくる方がいいかもしれません).


best-practice.tex

\newlength{\mytotalwidth}

\mytotalwidth=\dimexpr\linewidth-5mm
\newlength{\mycolumnwidth}
\mycolumnwidth=\dimexpr\mytotalwidth-5mm

\begin{frame}
\begin{block}{[totalwidth=\textbackslash{}mytotalwidth], [t]+[T], 0.5:0.5}
\fbox{
\begin{columns}[totalwidth=\mytotalwidth]
\begin{column}[t]{0.5\mycolumnwidth}
\indicatewidth{left}
\end{column}
\begin{column}[T]{0.5\mycolumnwidth}
\centering
\fbox{\includegraphics[width=20pt]{pic/0inN.png}}
\par\indicatewidth{right}
\end{column}
\end{columns}
}
\par\indicatewidth{outside}
\end{block}
\end{frame}


スクリーンショット 2016-02-13 21.41.44.png

もちろんこれは上揃えしたい場合の例であって,中央揃えの方が見栄え良い場合も多いでしょう.


まとめ


  • PGF の \pgfputat, \pgfxy によるオマジナイは使ってはいけません.


  • columns および column の幅は,余裕をもたせた値を指定しましょう.

  • 画像を上に揃えたいときは,[t][T] オプションを組み合わせましょう.

  • 最終手段として,絶対座標指定もできます.

3 年前の二の舞にならないためにも,TeXnitian の皆様からの御指摘,御指南,そしてより良いご提案をお待ちしています.






  1. 元を辿れば私が 2004 年の資料からろくに考えずにオマジナイをサルベージしてしまったことが発端ですから,そういう意味では 10 年モノのアレコードですね:( 



  2. Beamer は PGF に依存していますが,基本的にはコアパッケージ pgfcore.sty しか読み込みません.ですので,後方互換性のための命令は未定義となります.どうしてもこれらの命令を使いたい場合は,pgf.sty もしくはピンポイントで pgfcomp-version-0-65.sty を読み込めば使えるようになります. 



  3. 個人的には画像は右に置きたい派なのでこの文章はちょっとだけ気に食わないですけどね.まぁ文化や分野の違いもあるのかもしません. 



  4. PGF イディオムのほうがうまくいかないのは columns 環境のせいではありませんよ:) 




  5. T is similar to the t option, but T aligns the tops of the first lines while t aligns the so-called baselines of the first lines. If strange things seem to happen in conjunction with the t option (for example if a graphic suddenly “drops down” with the t option instead of “going up,”), try using this option instead. (Cf. texdoc beamer