ggplot2についてちょっと勉強した(3) -themeを利用した外観の変更-

グリッドの背景とかどうやって変えるのかなーとずっと思ってたんですが,どうやらggplot2ではthemeというものを使うようです.Tsukuba.R#6のid:syou6162の発表(Tsukuba.R#6の発表資料 - yasuhisa's blog)の最後で少し紹介がありましたが,そこでもthemeを設定する関数が使用されています.
それで調べてみるとかなりいろいろ設定できるということが分かったのと,まだ日本語の解説が無いっぽいのでまとめてみました.
参考: Introduction to data analysis. stat405.(Nov 9 のTheme elements)

theme

ggplot2ではthemeという概念によって外観を操作する.themeにより背景色やフォントなどの細かい調整が可能になる.組み込みで用意されているテーマにはtheme_bw()とtheme_grey()がある.デフォルトが灰色の背景に白いグリッドであるのに対し,theme_bw()は白背景に灰色のグリッドという外観を設定する.themeは他のlayerを適用するのと同様に'+'を使うことで適用出来る.

library(ggplot2)
hgram <- qplot(rating, data=movies, binwidth=1)
hgramt <- hgram + opts(title = "This is histogram!!!")
hgramt + theme_bw()


ちなみにtheme_grey()はデフォルトのセッティング.theme_bw(),theme_grey()を使用してthemeを適用した場合はベースサイズのみを指定できる.

hgramt + theme_bw(base_size=15)
hgramt + theme_grey(20)



以下,さらに細かい指定の方法.

element

操作可能なパラメータはelementという単位でそれぞれ名前が付いている.elementを操作することで外観の操作ができる.
Elementは大別すると以下の4種

  • Axis
    • 軸の線や軸に沿うテキストなどをコントロール
  • Legend
  • Panel
    • グリッド線やプロットの背景などをコントロール
  • Strip
    • facetでプロットを分割したとき,各プロットの上に付くラベル部をコントロール

element function

elementはopts()関数とelement functionを使うことでローカルに(そのプロットに限り)変更できる.グローバルに変更する方法は後述する.
element functionはtheme_text(),theme_line(),theme_segment(),theme_rect(),theme_blank()の5種(分類としては4種)用意されている.
あるelementに対して使用できるelement functionは決まっている.以下に一覧を示す.

Theme element 使えるfunction elementの説明
axis.line segment 軸の線
axis.text.x text x軸ラベル
axis.text.y text y軸ラベル
axis.ticks segment 軸のチックマーク
axis.title.x text x軸タイトル
axis.title.y text y軸タイトル
legend.background rect 凡例背景
legend.key rect 凡例キー下の背景
legend.text text 凡例ラベル
legend.title text 凡例タイトル
panel.background rect プロットパネル内の背景
panel.border rect プロットパネル周囲のボーダー
panel.grid.major line 主グリッド
panel.grid.minor line 補助グリッド
plot.background rect プロットの背景
plot.title text タイトル
strip.background rect facetのラベル背景
strip.text.x text facetラベル(水平方向)
strip.text.y text facetラベル(垂直方向)

なお,element functionとtheme_bw(),theme_grey()は併用可能だが,theme_bw(),theme_grey()を実行するとすべてのエレメントが変更されてしまうので,theme_bw(),theme_grey()は最初に追加するようにする.

## これはtheme_bw()だけ適用される
hgramt + opts(plot.title = theme_text(size=20)) + theme_bw()
## theme_bw()の後から設定を追加(もしくは変更)
hgramt + theme_bw() + opts(plot.title = theme_text(size=20))

以下,各element functionの説明と実行例.

theme_text()

theme_text()関数はラベルやタイトルのテキストをコントロールする.フォントの種類,サイズ,色,縦横の位置,角度,行間などを制御できる.

hgramt + opts(plot.title = theme_text(
                size=20,        ## フォントサイズ
                face="italic",  ## 文字スタイル
                colour="red",   ## 色
                hjust=0,        ## 水平位置
                vjust=1,        ## 垂直位置
                angle=-45))     ## 角度


※イタリックがきいてないのはプロットに使ったCairoパッケージの影響っぽい

## 行間の調整
hgramt + opts(title = "This \n is \n histogram",
              plot.title = theme_text(lineheight=2))

theme_line(), theme_segment()

theme_line(),theme_segment()はいずれも線をコントロールするが,theme_line()はグリッド,theme_segment()は軸ラインなどを制御し,使い分ける必要がある.

## 主グリッドの太さ,色,線種の変更
hgram + opts(panel.grid.major = theme_line(size=1, colour="blue", linetype="dotted"))

## 軸ラインの太さ,色,線種の変更
hgram + opts(axis.line = theme_segment(size=2, colour="red", linetype = "dashed"))

theme_rect()

theme_rect()は矩形領域に対する操作を行う.背景色の変更,ボーダーの色や太さ,線種の変更などができる.

## 背景色グレー,枠線を太くし,色を赤に
hgram + opts(plot.background = theme_rect(fill="grey", size=2, colour="red"))

## 太い破線で囲う
hgram + opts(panel.background = theme_rect(size=3, linetype="dotted"))

theme_brank()

theme_brank()は何も描画しない.theme_brank()を表示したくないelementに対して使用することでそのelementを非表示にできる.

## 元のプロット
hgramt

## 補助グリッドを消す
last_plot() + opts(panel.grid.minor = theme_blank(),
                   panel.grid.minor = theme_blank(),
                   panel.background = theme_blank(),
                   axis.title.x = theme_blank(),
                   axis.title.y = theme_blank())


ここで使用したlast_plot()は直前のプロットを呼び出す関数.プロットを少しずつ修正するのに使える.

## 軸のラインだけ追加
last_plot() + opts(axis.line = theme_segment())

themeのグローバルな変更とthemeの自作

themeをグローバルに変更する(つまり,それ以降に描画されるすべてのグラフに変更を適用する)方法はいくつかあるが,一つは最初にも示したtheme_set()関数を使用する方法である.

theme_set(theme_bw())

ただしこの方法では完全なセットになっているリストを与えないといけない.自作したリストを適用する場合にはこれが便利だろう.
もう一つはtheme_update()関数を使うやり方.par()でグラフィックパラメータを指定するのと同じような感覚で使用できる.
また,par()でパラメータを設定するときのように,実行時に代入することで古いパラメータを保存しておける.

## theme_update()
old_theme <- theme_update(
                          plot.background = theme_rect(fill="#3366FF"), 
                          panel.background = theme_rect(fill = "#003DF5"), 
                          axis.text.x = theme_text(colour = "#CCFF33"), 
                          axis.text.y = theme_text(colour = "#CCFF33", hjust = 1), 
                          axis.title.x = theme_text(colour = "#CCFF33", face = "bold"), 
                          axis.title.y = theme_text(colour = "#CCFF33", face = "bold", angle = 90)
                          )
mtc <- qplot(mpg, wt, data=mtcars, facets = .~cyl)
mtc
theme_set(old_theme)


現在のthemeがどのようになっているのかはtheme_get()で確認できる.

> theme_get()
$axis.line
theme_blank()

$axis.text.x
theme_text(colour = "grey50", size = base_size * 0.8, vjust = 1, 
    lineheight = 0.9)

$axis.text.y
theme_text(colour = "grey50", size = base_size * 0.8, hjust = 1, 
    lineheight = 0.9)

... *snip*

また,theme_get()の例からも分かるようにthemeは沢山の項目が並んだリストなので,theme_bw()などをテンプレートとして簡単にthemeを自作できる.

mytheme <- theme_bw()
mytheme$panel.background <- theme_rect(fill="skyblue")
old_theme <- theme_set(mytheme)
hgram
theme_set(old_theme)