この記事では,LaTeX Beamer で画像をいい感じの位置に置く方法,特に columns
環境を使う方法を扱います.
§.0. ことの始まり
後輩氏「Beamer で画像挿入うまくいかないんやで.コレ見てやってみたんやで.」
私氏「誰やこんなクソみたいなコード書いたやつは.あ,私やんけ.」
Google氏「『Beamer 画像』で上の方に出しといてあげたやで.」
私氏「マジかよ勘弁しちくり〜〜〜」
そういうわけで,3 年前のアレなコード1に引導を渡すべく,Beamer で画像を意図通り配置するための本当のベストプラクティスについて考察していきたいと思います.
§.1. はじめに
本稿のサンプルは,執筆時にいくつかの環境 (TeX Live 2015 / Mac OS X, TeX Live 2014 / Debian Jessie, etc.) にてタイプセットできることを確認しています.以下に,サンプル用のコマンド定義を含むプリアンブルを示します.
\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
がちょっと外側にはみ出ている様子が分かります.
そこで [onlytextwidth]
オプションを指定したところが次の図です.このオプションは [totalwidth=\textwidth]
と同じ効果をもち,columns 領域幅をちょうど一行分だけとるということです.中に収まりましたが今度は中央がくっつきました.
中央がくっついているのは,幅の合計が 1 にならないようにすると解消されます.columns
環境はマージンのことまでよしなにはしてくれませんから,合計をぴったり 1 にするよりも,適当にバッファを持たせる方が見た目よく振舞うことが多いです.右側余白が小さい問題も,totalwidth
を適当に 1 より小さい幅を指定するのが簡単です(やはりマージンのことまでよしなにはしてくれません).
まとめると,columns
の totalwidth
および各 column
の幅は,ぴったりの値より小さめに設定するのが良いです.
参考に,3 段組の場合も掲載しておきます.
\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}
あらまーひどい! まぁちょっと考えれば分かることなんですが,これはアラインメントオプション [t]
によるものです(さっきから明示的に指定していましたがこれは columns
環境のデフォルトです).[t]
は各カラムの一行目のベースラインを上揃えするものですから,各カラムの最初の行の高さが違えばこのとおり!
columns
の幅指定に余裕をもたせて,横にはみ出る問題も解消してあります.この上揃いが \includegraphics
と columns
を組み合わせたときの不細工なレイアウトの正体です.したがって,アラインメントオプションを適切に指定することで解消できます.それぞれのオプションの意味は以下のとおりです.
-
[t]
: 上揃え(一行目ベースライン) -
[T]
: 上揃え(一行目上端) -
[c]
: 中央揃え -
[b]
: 下揃え
[T]
を使うことでベースラインではなく上端基準で揃えられるので,画像を組み合わせる場合はこのオプションを使うといいでしょう5.また,columns
ではなく個別の column
にアラインメントを指定することで,途中でアラインメントを変更することもできます.上の [T]
の例では,文章・画像ともに少し上にはみ出ていますが,[t]
と [T]
を使い分けることでいい感じになります.
左の 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}
あ,ハイ,今度はそうなるんですね.
分かりづらいですが,figure
環境の作る余白の分だけ下がって上揃えされています.そもそも Beamer での figure
は floating box ではなくただ center
環境をラップしたものです.この空白が嫌であれば,figure
環境ではなく \centering
を使うべきです.\caption
をつけたいなどの理由があってかつどうしても上に詰めたければ,段落一行分くらいのネガティブスペースを入れるしかないでしょう.
[こらむ]: \ナントカ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
ではなくそれらしいマージンの値を引っ張ってくる方がいいかもしれません).
\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}
もちろんこれは上揃えしたい場合の例であって,中央揃えの方が見栄え良い場合も多いでしょう.
まとめ
- PGF の
\pgfputat
,\pgfxy
によるオマジナイは使ってはいけません. -
columns
およびcolumn
の幅は,余裕をもたせた値を指定しましょう. - 画像を上に揃えたいときは,
[t]
と[T]
オプションを組み合わせましょう. - 最終手段として,絶対座標指定もできます.
3 年前の二の舞にならないためにも,TeXnitian の皆様からの御指摘,御指南,そしてより良いご提案をお待ちしています.
-
元を辿れば私が 2004 年の資料からろくに考えずにオマジナイをサルベージしてしまったことが発端ですから,そういう意味では 10 年モノのアレコードですね:( ↩
-
Beamer は PGF に依存していますが,基本的にはコアパッケージ
pgfcore.sty
しか読み込みません.ですので,後方互換性のための命令は未定義となります.どうしてもこれらの命令を使いたい場合は,pgf.sty
もしくはピンポイントでpgfcomp-version-0-65.sty
を読み込めば使えるようになります. ↩ -
個人的には画像は右に置きたい派なのでこの文章はちょっとだけ気に食わないですけどね.まぁ文化や分野の違いもあるのかもしません. ↩
-
PGF イディオムのほうがうまくいかないのは
columns
環境のせいではありませんよ:) ↩ -
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
)