読者です 読者をやめる 読者になる 読者になる

ggplot2 の自分用メモ集を作ろう

R ggplot2
  1. プロットの作製
  2. スケールと軸
  3. 凡例
  4. テーマ (グラフ背景・グリッドの色, マージン, フォント)
  5. 保存
  6. 個別のグラフと高度なグラフ
  7. 参考 URL
  8. その他

はじめに

この記事が最初に書かれてから既に5年以上が経過しました。
ggplot2 の v2.0.0 では大幅に仕様が変更されたため、各所に公開されている以前のプログラムがそのままでは動かない場合もあります。
そのため、2016/01/08 に本記事の内容を v2.0.0 に併せて全面的に改定しました。
最新版の マニュアル や、Web 上に配信されている v2.0.0 以降向けの新しい情報も併せてご参照下さい。
記録として、古い情報は 別のページ に移動しました。


基本プロットを作る

ggplot2 における作図の基本的な手順は、

  1. ggplot() にデータフレームと各軸や層に対応する変数名を指定
  2. 書きたいグラフに対応する geom_xxx() もしくは stat_xxx() を足す

の二つが分かっていれば OK です。
これに加えて、軸やラベルや凡例などのその他の細かいオプションを指定できます。
ggplot2 では様々な geom_xxx()stat_xxx() が定義されているので、まずは各々がどのようなグラフに対応しているのかをまとめました。
以下のリストは ggplot2-cheatsheet-2.0 を参考に少し情報を加えています。

require("ggplot2")
df <- data.frame(
  d  = (d  <- sample(c("a", "b", "c", "d"), 100, replace = TRUE)),
  x  = (x  <- rnorm(100)),
  y  = (y  <- 10 + rnorm(100, x)),
  zx = (zx <- (rep(1:10, 10) - 5) / 2),
  zy = (zy <- (rep(1:10, each = 10) - 5) / 2),
  z  = (z  <- zx*zy),
  g  = rep(1:2, 50),
  h  = c(rep(1, 50), rep(2, 50))
)
df <- df[order(df$y),]
df$w <- 1:100
df$gp <- factor(df$g, labels = c("alpha", "beta"))
sdf <- subset(df, w <= 10)
edf <- do.call(rbind, by(df, df$d, function(df) unlist(t.test(df$y)[4:5])))
edf <- data.frame(x = row.names(edf), y = edf[,3], ymin = edf[,1], ymax = edf[,2])

d1 <- ggplot(df,  aes(d))
d1 + geom_bar()

c1 <- ggplot(df,  aes(x))
c1 + geom_histogram(aes(y = ..density..))
c1 + geom_histogram(aes(y = ..count..))
c1 + geom_area(stat = "bin")
c1 + geom_dotplot()
c1 + geom_freqpoly()
c1 + geom_density(kernel = "gaussian")
c1 + geom_density() + stat_function(fun = dnorm)
c1 + geom_density() + stat_function(fun = dnorm, arg = list(mean = -1))
s1 + stat_qq()

s1 <- ggplot(df, aes(sample = x))
c1 + stat_ecdf()

d2s <- ggplot(sdf, aes(factor(w), y))
d2s + geom_bar(stat = "identity")

d2 <- ggplot(df, aes(d, y))
d2 + geom_boxplot()
d2 + geom_violin()
d2 + geom_dotplot(binaxis = "y", stackdir = "center")

d2e <- ggplot(edf, aes(x, y, ymin = ymin, ymax = ymax))
d2h <- ggplot(edf, aes(y, x, xmin = ymin, xmax = ymax))
d2e + geom_errorbar()
d2h + geom_errorbarh()
d2e + geom_linerange()
d2e + geom_pointrange()
d2e + geom_crossbar()
d2 + stat_summary(fun.data = "mean_cl_normal", geom = "errorbar", width = 0.1)
d2 + stat_summary(fun.data = "mean_cl_normal", geom = "pointrange")

c2 <- ggplot(df, aes(x, y))
c2 + geom_point()
c2 + geom_smooth(method = "lm")
c2 + geom_smooth(method = "loess")
c2 + geom_smooth(method = "gam")
c2 + geom_smooth(method = "rlm")
c2 + geom_quantile()
c2 + geom_rug()
c2 + geom_point() + stat_ellipse()
c2 + geom_point() + geom_text(aes(label = d), nudge_x = -0.1, nudge_y = 0.2)
c2 + geom_point() + geom_label(aes(label = d), nudge_x = -0.1, nudge_y = 0.2)
c2 + geom_bin2d()
c2 + geom_hex()
c2 + geom_density2d()
c2 + stat_function(fun = exp)

c2p <- ggplot(sdf, aes(w, y))
c2p + geom_line()
c2p + geom_area()
c2p + geom_step()

c3 <- ggplot(df, aes(zx, zy))
c3 + geom_contour(aes(z = z))
c3 + geom_raster(aes(fill = z), interpolate = TRUE)
c3 + geom_tile(aes(fill = z))

次元 変数の型 グラフタイプ グラフ名 geom, stat
1次元 離散 棒グラフ 棒グラフ d1 + geom_bar()
連続 ヒストグラム ヒストグラム
c1 + geom_histogram()

# ..density.. と ..count.. は以下のヒストグラム型のグラフでも同様に使用できる

c1 + geom_histogram(aes(y = ..density..)) # y軸を density に

c1 + geom_histogram(aes(y = ..count..)) # default
ヒストグラム (エリアプロット) c1 + geom_area(stat = "bin")
ヒストグラム (ドットプロット) c1 + geom_dotplot()
ヒストグラム (折れ線) c1 + geom_freqpoly()
密度推定 c1 + geom_density(kernel = "gaussian")

# kernel = c("gaussian", "epanechnikov", "rectangular", "triangular", "biweight", "cosine", "optcosine")
任意の関数の描画 任意の関数の描画 c1 + geom_density() + stat_function(fun = dnorm)

c1 + geom_density() + stat_function(fun = dnorm, arg = list(mean = -1))
経験分布関数 経験分布関数 c1 + stat_ecdf()
Q-Q プロット Q-Q プロット s1 + stat_qq()
2次元 離散 × 連続 棒グラフ 棒グラフ d2s + geom_bar(stat = "identity")
箱ひげ図 箱ひげ図 d2 + geom_boxplot()
バイオリンプロット d2 + geom_violin()
Bee swarm プロット d2 + geom_dotplot(binaxis = "y", stackdir = "center")
範囲の表示 エラーバープロット d2e + geom_errorbar()

d2h + geom_errorbarh()
エラーバープロット (linerange) d2e + geom_linerange()
エラーバープロット (pointrange) d2e + geom_pointrange()
エラーバープロット (crossbar) d2e + geom_crossbar()
統計処理 + エラーバープロット d2 + stat_summary(fun.data = "mean_cl_normal", geom = "errorbar", width = 0.1)

d2 + stat_summary(fun.data = "mean_cl_normal", geom = "pointrange")
連続 × 連続 散布図 散布図 c2 + geom_point()
線形回帰 c2 + geom_smooth(method = "lm")
loess (n が多い場合は注意) c2 + geom_smooth(method = "loess")
GAM (generalized additive model) c2 + geom_smooth(method = "gam")
ロバスト回帰 (rlm) c2 + geom_smooth(method = "rlm")
分位点回帰 c2 + geom_quantile()
散布図の装飾 Rug c2 + geom_rug()
楕円 c2 + geom_point() + stat_ellipse()
文字を表示 c2 + geom_point() + geom_text(aes(label = d), nudge_x = -0.1, nudge_y = 0.2)
ラベルを表示 (装飾向き) c2 + geom_point() + geom_label(aes(label = d), nudge_x = -0.1, nudge_y = 0.2)
二次元密度推定 二次元密度推定 (矩形) c2 + geom_bin2d()
二次元密度推定 (六角形) c2 + geom_hex()
二次元密度推定 (等高線) c2 + geom_density2d()
任意の関数の描画 任意の関数の描画 c2 + stat_function(fun = exp)
折れ線グラフ 折れ線グラフ c2p + geom_line()
折れ線グラフ (曲線下を塗りつぶし) c2p + geom_area()
階段関数 c2p + geom_step()
地図 地図 geom_map()
その他の基本グラフ 何も描画しない geom_blank()
線分 (始点と終点を指定) geom_segment()
線分 (位置と角度と半径を指定) geom_spoke()
曲線 geom_curve()
パス geom_path()
geom_ribbon()
矩形 geom_rect()
ポリゴン geom_polygon()
3次元 連続 × 連続 × 連続 等高線プロット 等高線プロット c3 + geom_contour(aes(z = z))
ラスタ c3 + geom_raster(aes(fill = z), interpolate = TRUE)
タイル c3 + geom_tile(aes(fill = z))
簡単にグラフを作りたい場合は、簡易版の qplot() も利用可能ですが、本稿では説明しません。

Geoms

Geoms (geometric objects の略) はグラフ (graphics) の元になる幾何学図形 (geometric graphs) の事です。
点や区間 (1次元では線分、2次元では長方形、・・・) や、それらを集めたもの (経路や領域、また "箱" と "ひげ" の組み合わせなどの複雑な図形も含む) などがこれにあたります。
例えば、散布図では点、折れ線グラフでは線分を用います。

統計的なグラフを作るためには、統計的な変換が必要になる場合が少なくないため、ggplot2 ではグラフの種類に応じて geom_xxx()stat_xxx() という geoms と statistics (データの統計的な変換) を組み合わせた関数が定義されています。
例えば、geom_point(stat = "identity") は、統計処理を何もしないで幾何学図形として点を用いることを意味します。

Aesthetics

Aesthetics は位置、色、大きさなどの、幾何学図形の集まりをグラフとして知覚できるようにする様な特性のことです (Wilkinson 2005)。
例えば、散布図はそれぞれの観測値を点という幾何学図形で表わし、点の位置がそれぞれの観測値における二つの変数の値を表わします (Wickham 2009)。
さらに、異なる色をグループに割り当てたり、データの数によって大きさを変更するなどのルールを定めることで、単なる幾何学図形の集合を色々な情報を得ることができるグラフに変換することができます。
グラフの種類によって必須な aesthetics は異なります。
以下は ggplot2 で使われる aesthetics のリストです。

adj, alpha, angle, bg, cex, col, color,
colour, fg, fill, group, hjust, label, linetype, lower,
lty, lwd, max, middle, min, pch, radius, sample, shape,
size, srt, upper, vjust, weight, width, x, xend, xmax,
xmin, xintercept, y, yend, ymax, ymin, yintercept, z

この中でも、

x, y, z, colour, fill, group, shape, size

などは利用頻度が高いと思います。

ggplot2 では必須な aesthetics とデータに含まれる変数を aes を使って対応付けることができます。

# ggplot 関数のデフォルト引数
ggplot(data = NULL, mapping = aes(), ..., environment = parent.frame())

ggplot の二番目の引数が対応付けを指定する部分です。
data = mapping = の部分は省略可能で、

ggplot(df, aes(x = x, y = y, colour = factor(g)))

と書くことができます。
aes() についても x = y = の部分は省略可能で、

aes(x, y, colour = factor(g))

と書くことができます。

また、aesthetics は aes で対応づけず、固定した値として使用することもできます。
例えば、

ggplot(df, aes(x, y, shape = factor(g))) + geom_point(colour = "blue")

と書けば、点の形はグループ毎に変わり、点の色は全て青色になります。

Geoms の種類と指定可能な aesthetics ついては ggplot2-cheatsheet-2.0aesの一覧表を見たい が大変参考になります。

違う種類のグラフを重ねる

共通のデータフレームを用い、aesthetics も全く同じで良い場合は、geom や stat を + でつなぐだけで異なる種類のグラフを重ねてゆくことができます。

# 散布図に線形回帰直線と信頼区間を重ねて描画
c2 +
  geom_point() +
  geom_smooth(method = "lm")

共通のデータフレームを用い、aesthetics が異なる場合は、それぞれの geom や stat で必要な aesthetics の対応付けを追加・変更します。

# 散布図の各点にラベルを追加
c2 +
  geom_point() +
  geom_label(aes(label = d), nudge_x = -0.1, nudge_y = 0.2)

各データフレームが異なる場合、2つ目以降の geom や stat 等に data = mapping = aes() を加えます。

# 散布図の描画と、変数 d が "a" の点のみにラベルを追加
c2 +
  geom_point() +
  geom_label(data = subset(df, d == "a"), aes(label = d), nudge_x = -0.1, nudge_y = 0.2)

参照線の追加

geom_vline や を用います。
線種については ヘルプ を参照するとよいでしょう。

# linetype: 0 = blank, 1 = solid, 2 = dashed, 3 = dotted, 4 = dotdash, 5 = longdash, 6 = twodash
c2 + geom_point() + geom_vline(xintercept = 0, linetype = "solid")
c2 + geom_point() + geom_vline(xintercept = c(0, 1, 2), linetype = "dotted")
c2 + geom_point() + geom_hline(yintercept = 10, linetype = 1)

参考:Add a dotted vertical line on certain x-axis values using ggplot (Stack Overflow)

グループ分け

一つのグラフの中で複数のグループの情報を表示したいことはよくあります。
グループ分け表示の指定の仕方はグラフの種類によって異なりますが、点や線を利用している場合は、aesthetics の対応付けに colour を追加します。

c2g <- ggplot(df, aes(x, y, colour = d))
c2g + geom_point()

棒グラフの様な塗りつぶし型のグラフの場合は、aesthetics の対応付けに fill を追加します。

d2sg <- ggplot(sdf, aes(factor(w), y, fill = factor(w)))
d2sg + geom_bar(stat = "identity")

使用している geom や stat の種類によって必要な aesthetics は変わるため、適宜 ヘルプ を参照するとよいでしょう。
ggplot2-cheatsheet-2.0aesの一覧表を見たい も参考になります。

層別プロット

層別したグラフを並べて比較したい場合、

c2g + geom_point() + facet_grid(. ~ g)
c2g + geom_point() + facet_grid(g ~ .)
c2g + geom_point() + facet_grid(g ~ h)
c2g + geom_point() + facet_wrap( ~ g, nrow = 2, ncol = 1)

の様に記述します。
facet_grid() では指定した方向にグラフを並べていきます (行 ~ 列)。
facet_wrap() では指定した行数 × 列数に埋まるようにグラフを層毎に順番に並べて配置し、表示します。

軸スケールを層ごとに変更したい場合、

c2g + geom_point() + facet_wrap( ~ g, scales = "free_x")
c2g + geom_point() + facet_wrap( ~ g, scales = "free_y")
c2g + geom_point() + facet_wrap( ~ g, scales = "free")

の様に記述します。
"free_x" では x 軸が、"free_y" では y 軸が、"free" では両軸のスケールがデータに応じて自動的に変更されます。

層別したグラフでは、層の名前をラベルとして各グラフの上部に表示します。
このラベルの表示形式を変更したい場合、labeller を使用します。

c2g + geom_point() + facet_grid(. ~ g, labeller = label_both)
c2g + geom_point() + facet_grid(g ~ ., labeller = label_bquote(rows = alpha[.(g)]))
c2g + geom_point() + facet_grid(. ~ g, labeller = label_bquote(cols = alpha[.(g)]))
c2g + geom_point() + facet_grid(. ~ gp, labeller = label_parsed)

label_both を指定すると、「g: 1」「g: 2」の様に変数名と水準の両方が表示されます。
label_bquote や label_parsed ラベルに数式を利用したい場合に有用です、記法については labellerplotmath について参照するとよいでしょう。

Scales

ggplot2 には様々なスケールが定義されており、プロット時のグループ表示や、プロットの塗り分けに使うスケールや、軸の設定に使うスケールがあります。
使用できるスケールは aesthetics の種類によって変わるので、以下にまとめてみます。

Aesthetics タイプ Scales 説明
x, y 軸スケール scale_*_continuous 連続変数軸スケール
scale_*_discrete 離散変数軸スケール
scale_*_date 年月日軸スケール
scale_*_datetime 年月日時間軸スケール
scale_*_log10 常用対数スケール
scale_*_sqrt 平方根スケール
scale_*_reverse 反転スケール
color, fill 色によるグループ分け・離散 scale_*_brewer RColorBrewer のパレット色スケール
scale_*_grey グレーの色スケール
scale_*_hue 色相の色スケール
scale_*_discrete scale_*_hue の別名
scale_*_manual マニュアルの色スケール
scale_*_identity データの値に基づく色スケール
色によるグループ分け・連続 scale_*_gradient 2色のグラデーションの色スケール
scale_*_continuous scale_*_gradient の別名
scale_*_gradient2 3色のグラデーションの色スケール
scale_*_gradientn n色のグラデーションの色スケール
alpha 透過度によるグループ分け・離散/連続 scale_alpha_continuous 連続変数の透過度スケール
scale_alpha_discrete 離散変数の透過度スケール
scale_alpha_manual マニュアルの透過度スケール
scale_alpha_identity データの値に基づく透過度スケール
size 大きさによるグループ分け・離散/連続 scale_size_continuous 連続変数の大きさスケール
scale_size_area 面積に比例させた大きさスケール (連続)
scale_radius 半径に比例させた大きさスケール (連続)
scale_size_discrete 離散変数の大きさスケール
scale_size_manual マニュアルの大きさスケール
scale_size_identity データの値に基づく大きさスケール
linetype 線種によるグループ分け・離散 scale_linetype_discrete 離散変数の線種スケール
scale_linetype_manual マニュアルの線種スケール
scale_linetype_identity データの値に基づく線種スケール
shape 記号によるグループ分け・離散 scale_shape_discrete 離散変数の記号スケール
scale_shape_manual マニュアルの記号スケール
scale_shape_identity データの値に基づく記号スケール

軸ラベルやタイトルの変更

いくつかの指定方法がありますので、好みのものを利用するとよいでしょう。

# 軸ラベルの指定
c2 + xlab("axis.x.label")
c2 + ylab("axis.y.label")
c2 + labs(x = "axis.x.label", y = "axis.y.label")

# グラフタイトルの指定
c2 + ggtitle("TITLE")

# 一括指定
c2 + labs(title = "TITLE", x = "axis.x.label", y = "axis.y.label")

適宜 ヘルプ も参照するとよいでしょう。

軸の表示範囲を変更する

純粋に表示範囲だけを変更したい場合、coord_cartesian を利用します。

c2 + geom_point() + geom_smooth(method = "lm") +
  coord_cartesian(xlim = c(-1, 1), ylim = c(6, 14))

範囲外のデータを削除してグラフを作成する場合は、lims (xlim と ylim) を用います。

c2 + geom_point() + geom_smooth(method = "lm") + lims(x = c(-1, 1), y = c(6, 14))
c2 + geom_point() + geom_smooth(method = "lm") + xlim(-1, 1) + ylim(6, 14)
d2 + geom_boxplot() + xlim("a", "b")

軸の左右の余白を削除する

scale_*_*expand を用います。

c2 + geom_point() + scale_x_continuous(expand = c(0, 0))
c2 + geom_point() + scale_y_continuous(expand = c(0, 0))
d2 + geom_boxplot() + scale_x_discrete(expand = c(0, 0))

軸表示の修飾

scale_*_*labels を用います。

c2 + geom_point() + scale_x_continuous(labels = c("1st", "2nd", "3rd", "4th", "5th", "6th"))

また、scales パッケージを用いると、

require("scales")
c2 + geom_point() + scale_y_continuous(labels = percent)
c2 + geom_point() + scale_y_continuous(labels = dollar)
c2 + geom_point() + scale_x_continuous(labels = math_format(alpha + frac(.x, 2)))

comma_format, dollar_format, percent_format, scientific_format, parse_format, math_format などを用いて簡単に軸表示を修飾できます。

日時の軸スケール

scale_*_datescale_*_datetime を用います。

tdf <- data.frame(
  date = Sys.Date() - 0:29,
  price = runif(30)
)
ggplot(tdf, aes(date, price)) + geom_line() + scale_x_date(date_labels = "%b-%d")
ggplot(tdf, aes(date, price)) + geom_line() + scale_x_date(labels = date_format())

scales パッケージの date_format や、R の Date に関する情報も参照するとよいでしょう。

軸区切り値の変更

scale_*_* の breaks や labels を適宜用います。
任意の区切り、任意の表示が可能になります。

c2 + geom_point() +
  scale_x_continuous(
    breaks = seq(-1, 3, by = 1),
    labels = c("1st", "2nd", "3rd", "4th", "5th")
  )
d2 + geom_boxplot() +
  scale_x_discrete(
    breaks = c("a", "b", "c", "d"),
    labels = c(expression(alpha), expression(beta),
               expression(gamma), expression(delta))
  )

ヘルプ (scale_continuous, scale_discrete) も参照するとよいでしょう。

軸スケールの変更と変数変換

軸のスケールだけを変更したい場合、coord_trans を用います。

c2l <- ggplot(df, aes(x + 10, y^3))
c2l + geom_point() + geom_smooth(method = "lm") +
  coord_trans(x = "log10",  y = "log10")

coord_trans を用いると、統計処理等が行われた後で座標系 (軸のスケール) だけが変更されます。
上記の例では回帰直線を引いた後に対数座標系に変更が行われるため、最終的には曲線が描画されます。

変数変換をしたい場合は、scale_*_log10scale_*_continuous の trans を用います。

# 以下二つは全く同じ結果
c2l + geom_point() + geom_smooth(method = "lm") +
  scale_x_log10() + scale_y_log10()
c2l + geom_point() + geom_smooth(method = "lm") +
  scale_x_continuous(trans = "log10") + scale_y_continuous(trans = "log10")

こちらは純粋な変数変換のため、変換の後に統計処理等が行われます。
coord_trans とは異なり、最終的には直線が描画されます。

他にも 変換可能な関数 として

asn, atanh, boxcox, exp, identity, log, log10, log1p, log2,
logit, probability, probit, reciprocal, reverse, sqrt

などがあるようです。
ただし、scale_*_log10, scale_*_reverse, scale_*_sqrt 以外は定義されていないため、scale_*_continuous の trans からのみ利用可能なようです。
coord_trans でもこれらの関数を利用できます。

離散型変数の水準をソートしてプロット

離散型変数を含むデータをプロットした場合に、軸の並び順が望むようにならない場合があります。
そのような場合は、データフレームを編集して任意の順番に並び替える必要があります。
以下は reorder を用いたソートの例です。

d <- data.frame(
  x = c("80-", "90-", "100-", "110-", "120-", "130-", "140-", "150-", "160-", "170-", "180-"),
  y = c(0, 9, 35, 81, 194, 276, 271, 207, 138, 55, 59),
  z = seq(1, 11)
)
# うまくいかないケース
ggplot(d, aes(x, y)) +
  geom_bar(stat = "identity") +
  xlab("Systolic blood pressure [mmHg]") +
  ylab("Frequency")

# reorder を用いて順番に並べかえる
ggplot(d, aes(reorder(x, z), y)) +
  geom_bar(stat = "identity") +
  xlab("Systolic blood pressure [mmHg]") +
  ylab("Frequency")

基本的にはデータフレームを編集し、factor 型の変数の levels を並べ替えます。
例えば箱ひげ図では levels を直接並べ替える必要があるでしょう。

rdf <- df
rdf$d <- factor(rdf$d)
levels(rdf$d) <- rev(levels(rdf$d))

# a, b, c, d の順に表示
ggplot(df, aes(d, y)) + geom_boxplot()

# d, c, b, a の順に表示
ggplot(rdf, aes(d, y)) + geom_boxplot()

色々な方法が考えられますので、適宜 reorder, rev, order, with, transform などを参照のうえ好みの方法を見つけるとよいでしょう。

座標系の反転:横向き箱ひげ図

x 座標と y 座標を反転したい場合、coord_flip を用います。

# 横向き箱ひげ図
d2 + geom_boxplot() + coord_flip()

極座標への変換:円グラフ

円グラフを作成したい場合、coord_polar を用います。

d1p <- ggplot(df,  aes(1, fill = d))

# 積み上げ棒グラフ
d1p + geom_bar(position = "fill") +
  xlab(NULL) + ylab(NULL)

# 円グラフ
d1p + geom_bar(position = "fill") + coord_polar(theta = "y", direction = 1) +
  xlab(NULL) + ylab(NULL)

この例では、1次元棒グラフ (stat = "count") をグループで色分けして積み上げ棒グラフにしたものを極座標変換することで円グラフにしています。
ぱっと思いつきませんが、他にも極座標を使ったグラフはあるかもしれませんね。

座標系のアスペクト比の指定

x 座標と y 座標のアスペクト比を指定したい場合、coord_fixed を用います。

# y / x = 1 / 2
c2 + geom_point() + coord_fixed(ratio = 1/2)

# 比を分かりやすく表示
c2 + geom_point() + coord_fixed(ratio = 1/2) +
  scale_x_continuous(breaks = seq(-2, 4, by = 1)) +
  scale_y_continuous(breaks = seq(7, 15, by = 1))

グラフのアスペクト比を指定する訳ではない点に注意すべし。

色セットの変更

Scales の部分でも述べましたが、color, fill によって描画される幾何学図形の色をスケールの設定を通じて変更できます。

# デフォルト (以下の二つは同じ結果)
c2 + geom_point(aes(colour = d)) + scale_color_hue()
c2 + geom_point(aes(colour = d)) + scale_color_discrete()

# 色相の変更
c2 + geom_point(aes(colour = d)) + scale_color_hue(h = c(270, 360))

# グレースケール
c2 + geom_point(aes(colour = d)) + scale_color_grey()

# RColorBrewer の色セットの利用
c2 + geom_point(aes(colour = d)) + scale_color_brewer(palette = "Set1")
c2 + geom_point(aes(colour = d)) + scale_color_brewer(palette = "Pastel1")

因みに RColorBrewer で定義されているの色セット名一覧の表示と色一覧の表示を行う方法は以下のとおりです。

require("RColorBrewer")
rownames(brewer.pal.info)
display.brewer.all()

ggplot2 のデフォルト色セットの定義

ggplot2 ではデフォルトの色セットとして scale_*_hue を用いています。
scale_*_hue では水準の数によって自動的に適切な色が選ばれるため、どんな色が使われているのかを見る機会はあまりないと思います。
色の定義を参照したい場合は scales パッケージの hue_pal を用います。

require("scales")

# 3水準の時
hue_pal()(3)

# 5水準の時
hue_pal()(5)

参考:r - get list of colors used in a ggplot2 plot? - Stack Overflow

任意の色セットの利用

scale_*_manual では明示的にスケールを設定できるため、これを用いて任意の色セットを設定できます。

colours <- c("#D92121", "#9999FF", "#D92121", "#21D921")
c2 + geom_point(aes(colour = d)) + scale_colour_manual("Group", values = colours)

scale_*_manual の引数は name, breaks, labels, na.value, limits, guide であるためこれらも併せて設定できます。

凡例位置の変更

凡例位置を変更したい場合 theme の legend.position を用います。

c2g <- ggplot(df, aes(x, y, colour = d))
c2g + geom_point() + theme(legend.position = c(0.95, 0.05), legend.justification = c(1, 0))
c2g + geom_point() + theme(legend.position = "top")
c2g + geom_point() + theme(legend.position = "right")
c2g + geom_point() + theme(legend.position = "bottom")
c2g + geom_point() + theme(legend.position = "left")
c2g + geom_point() + theme(legend.position = "none")

凡例ラベルの変更

scalelabs を用います。

# 以下の二つは同じ結果
c2 + geom_point(aes(colour = d)) + scale_colour_hue("ラベル変更")
c2 + geom_point(aes(colour = d)) + labs(colour = "ラベル変更")

凡例を生成する複数の aesthetics を同時に設定している場合、同じラベルを設定することで全ての凡例を重ねて表示できる。

# 以下の二つも同じ結果
c2 + geom_point(aes(colour = d, shape = d)) + scale_colour_hue("同じラベル") + scale_shape_discrete("同じラベル")
c2 + geom_point(aes(colour = d, shape = d)) + labs(colour = "同じラベル", shape = "同じラベル")

凡例の一部を削除する

複数の凡例が用いられる場合、凡例の一部分を表示したくない場合もあります。
これを消したい場合、show.legend = FALSE オプションを用います。

# 凡例の背景が信頼区間の帯を考慮して黒くなる
c2 + geom_point(aes(colour = d)) + geom_smooth(aes(colour = d))

# 凡例を点だけにする
c2 + geom_point(aes(colour = d)) + geom_smooth(aes(colour = d), show.legend = FALSE)

Themes

theme 要素の設定を変更すると、テーマ (フォント、太字やイタリック、色、サイズ、マージン、縦横揃え、向き、一行の高さ、線種、塗りつぶし) の設定を行うことができます。
theme 要素の一覧を以下に示しました。
他の要素を継承している要素については、その要素の設定を個別で指定していないと継承している要素の設定が適用されます。

theme の要素 継承 タイプ 説明
line element_line 全ての line タイプの要素を一括指定
rect element_rect 全ての rect タイプの要素を一括指定
text element_text 全ての text タイプの要素を一括指定
title text element_text 全ての title タイプの要素を一括指定
aspect .ratio num グラフパネルのアスペクト比
axis .title title element_text 軸のラベル
.title.x axis.title element_text x 軸のラベルの個別指定
.title.y axis.title element_text y 軸のラベルの個別指定
.text text element_text 軸の目盛り線の数値や文字
.text.x axis.text element_text x 軸の目盛り線の数値や文字の個別指定
.text.y axis.text element_text y 軸の目盛り線の数値や文字の個別指定
.ticks line element_line 軸の目盛り線
.ticks.x axis.ticks element_line x 軸の目盛り線の個別指定
.ticks.y axis.ticks element_line y 軸の目盛り線の個別指定
.ticks.length unit 軸の目盛り線の長さ
.ticks.margin unit 2.0.0 で廃止され axis.ticks の margin で指定
.line line element_line 軸の線
.line.x axis.line element_line x 軸の線の個別指定
.line.y axis.line element_line y 軸の線の個別指定
legend .background rect element_rect 凡例の背景
.margin unit 凡例のマージン
.key rect element_rect 凡例要素の背景
.key.size unit 凡例要素の縦横幅
.key.height legend.key.size unit 凡例要素の縦幅
.key.width legend.key.size unit 凡例要素の横幅
.text text element_text 凡例要素のラベル
.text.align num 凡例要素の揃え方 (0, 1)
.title text element_text 凡例のタイトル
.title.align num 凡例のタイトルの揃え方 (0, 1)
.position chr/c(num, num) 凡例の位置 ("top", "bottom", "right", "left", c(x, x))
.direction chr 凡例値の配置方向 ("vertical", "horizontal")
.justification chr/c(num, num) 凡例の揃え位置 ("center", c(x, x))
.box chr 複数凡例の配置方向 ("vertical", "horizontal")
.box.just chr 複数凡例の揃え位置 ("top", "bottom", "left", "right")
panel .background rect element_rect パネルの背景
.border rect element_rect パネルのボーダー
.margin unit パネルのマージン
.margin.x panel.margin unit x 軸方向のパネルのマージンの個別指定
.margin.y panel.margin unit y 軸方向のパネルのマージンの個別指定
.grid.major line element_line グリッド線
.grid.major.x panel.grid.major element_line x 軸のグリッド線の個別指定
.grid.major.y panel.grid.major element_line y 軸のグリッド線の個別指定
.grid.minor line element_line 補助グリッド線
.grid.minor.x panel.grid.minor element_line x 軸の補助グリッド線の個別指定
.grid.minor.y panel.grid.minor element_line y 軸の補助グリッド線の個別指定
.ontop logical パネル (背景やグリッド線) をデータレイヤーの上に描画するか否か
plot .background rect element_rect グラフの背景
.title title element_text グラフのタイトル
.margin unit グラフの枠とパネル間のマージン
strip .background rect element_rect 層別プロット時の層ラベルの背景
.text text element_text 層別プロット時の軸の数値や文字
.text.x strip.text element_text 層別プロット時のx軸の数値や文字の個別指定
.text.y strip.text element_text 層別プロット時のy軸の数値や文字の個別指定
theme_bw() などの定義を参考に自分で上記のリストに基づいて theme を作成しても良いですし、theme() 関数を使って一部を変更することもできます。

element_text タイプの要素

以下のパラメータが指定できます。

  • family: フォントファミリー
  • face: フォントフェイス ("plain", "italic", "bold", "bold.italic")
  • colour/color: テキストの色
  • size: テキストのサイズ
  • hjust: x 軸方向の揃え位置 ([0, 1] の間の数値)
  • vjust: y 軸方向の揃え位置 ([0, 1] の間の数値)
  • angle: 角度 ([0, 360] の間の数値)
  • lineheight: 行の高さ
  • margin: マージン
  • debug: デバッグ (TRUE にすると該当部分を矩形で表示)
c2 + geom_point() + ggtitle("TITLE") + theme(plot.title = element_text(size = 20, face = "italic"))
element_rect タイプの要素

以下のパラメータが指定できます。

  • fill: 塗りつぶしの色
  • colour/color: 枠線の色
  • size: 枠線のサイズ
  • linetype: 枠線の線種
c2 + geom_point() + theme(plot.background = element_rect(fill = "grey80", colour = NA))
element_line タイプの要素

以下のパラメータが指定できます。

  • colour/color: 線の色
  • size: 線のサイズ
  • linetype: 線種
  • lineend: 線の終端のタイプ
c2 + geom_point() + theme(panel.grid.major = element_line(colour = "red"))
unit タイプの要素

unit(value, "unit") を設定できます。

c2 + geom_point() + theme(plot.margin = unit(c(0.5, 0.5, 0.5, 0.5), "cm"))

複数の値を指定できるものと、そうではないものがあるため注意が必要です。

element_blank

上には出てきませんでしたが、element_blank() という要素があり、これを設定する事で各要素を表示しないように変更することもできます。

c2 + geom_point() + theme(panel.grid.minor = element_blank())

定義済み theme の適用と編集

theme はフォントファミリー、フォントサイズ、背景色、グリット色、マージンなどの設定をまとめたものです。
定義済みのテーマを適用するだけで、グラフのデザインを簡単に変更することができます。
適用する方法は、

c2 + geom_point(aes(colour = d)) + theme_bw()
c2 + geom_point(aes(colour = d)) + theme_gray()
c2 + geom_point(aes(colour = d)) + theme_classic()
c2 + geom_point(aes(colour = d)) + theme_minimal()

このようになります。

ggplot2-2.0.0 では、

が利用できます。

デフォルトで使用するテーマを設定することもできます。

theme_set(theme_bw())

現在のテーマの設定を表示する方法は

theme_get()

テーマ定義の内部を参照する場合は

theme_bw

適宜ヘルプ (theme_set, theme_get, theme_update) を参照するとよいでしょう。

%+replace% を使って定義を変更すると (axis.text.x の vjust = 0.5 に変更してみた例)

my_theme_bw <- function(base_size = 16, base_family = "") {

  theme_bw(base_size = base_size, base_family = base_family) %+replace%
  theme(
    axis.text.x = element_text(vjust = 0.5)
  )

}

この例では my_theme_bw というオリジナルテーマを作成できます。

現在のテーマをバックアップしておいて、一部分だけ変更した後にグラフを描画して元に戻す場合。
theme_set(theme_gray())
old <- theme_update(panel.background = element_rect(colour = "pink"))
c2 + geom_point(aes(colour = d))
theme_set(old)
ggthemes package

現在までにも ggplot2 を拡張する様々なパッケージが公開されています。
ggthemes パッケージは、以下の様な追加の geom, theme, scale を提供しています。

  • 追加 geom (geom_rangeframe, geom_tufteboxplot)
  • 追加 theme (theme_base, theme_calc, theme_economist, theme_excel, theme_few, theme_fivethirtyeight, theme_gdocs, theme_hc, theme_par, theme_pander, theme_solarized, theme_stata, theme_tufte, theme_wsj)
  • 追加 scale (追加 theme 用に色関係の scale が多数)

theme 要素と theme() の併用時の注意点

theme() で指定できる設定の一部は theme_bw() などの後に付加する必要があります。

c2 + geom_point() + theme_bw() + theme(panel.grid.major = element_line(colour = "red"))

以下のようなスクリプトでは、theme_bw() が最後に適用されるため、メインのグリッド線は赤くなりません。

c2 + geom_point() + theme(panel.grid.major = element_line(colour = "red")) + theme_bw()

フォント変更

ggplot2 ではいくつかの方法でフォントを変更することができます。
もっとも簡単な方法は、定義済み theme の base_family にフォント名を指定する方法です。

c2 + geom_point() + theme_bw(base_family = "serif")

あまりないと思われますが、theme の各要素についてフォントを変更したい場合、element_text タイプの各要素の family をそれぞれ指定してください。
詳細は themes の記載を参照するとよいでしょう。

利用可能なフォント名は以下のように取得できます。

# Postscript 出力する場合
names(postscriptFonts())

# Windows でビットマップ出力する場合
# names(windowsFonts())

また、extrafont というパッケージを使うと、デバイス上にあるフォントを R で利用できるように自動で設定してくれます。

# 設定方法
# install.packages("extrafont")
library("extrafont")
font_import()
loadfonts()
loadfonts(device = "postscript")
# Windows でビットマップ出力する場合
# loadfonts(device = "win")

設定は一度でかまいませんので、次回以降は extrafont をロードするとフォントが使える状態になります。

# extrafont ロードしていない時はデフォルトのフォントのみが利用できる
names(postscriptFonts())
# names(windowsFonts())

# 設定済みフォントをロード
require("extrafont")
names(postscriptFonts())
# names(windowsFonts())

参考:How to use your favorite fonts in R charts

IPAフォントを利用する方法もあるようです。
参考:R: ggplot2でIPAフォント使用 (Taglibro de H)

ggsave 関数を利用してさまざまな形式で保存する

ggsave 関数は、保存先のパスとしてファイルの拡張子まで指定しておくとファイル形式を自動判別して保存くれます。

path <- ""
p <- c2 + geom_point()
ggsave(paste0(path, "save1.png"), p, width = 10, height = 10)
ggsave(paste0(path, "save1.pdf"), p)

グラフィックデバイスを Cairo に変更すると綺麗になるようです。

path <- ""
p <- c2 + geom_point() + theme_bw(base_family = "serif")
ggsave(paste0(path, "save1.png"), p)
ggsave(paste0(path, "save2.png"), p, type = "cairo-png")

参考:Using cairographics with ggsave()

日本語利用時の文字化けについて (EPS, PDF ファイルなど)

ggplot2 で描画したグラフを PDF や EPS 形式で出力すると日本語が文字化けする事があります。
これは、用いているフォントが日本語に対応していないことが原因です。
R がデフォルトでサポートしている日本語対応フォントは "Japan1", "Japan1HeiMin", "Japan1GothicBBB", "Japan1Ryumin" などですので、とりあえずこれらを使っていれば文字化けは回避できます。

path <- ""
p <- c2 + geom_point() + xlab("日本語") + theme_bw(base_family = "Japan1GothicBBB")
ggsave(paste0(path, "save1.pdf"), p)

自分で好みのフォントを R で使えるように設定してもよいでしょう。
参考:ggplot2で日本語が文字化けする件 (dichikaの日記)
参考:Using CJK Fonts in R and ggplot2 (Hi!!)

map プロット

geom_map[http://docs.ggplot2.org/current/coord_map.html:title=coord_map] が利用できます。

# install.packages("maps")
data <- data.frame(murder = USArrests$Murder, state = tolower(rownames(USArrests)))
map  <- map_data("state")
k    <- ggplot(data, aes(fill = murder))
k + geom_map(aes(map_id = state), map = map) + expand_limits(x = map$long, y = map$lat)

ggmap パッケージ等も map プロットに有用なようです。
参考:CRAN - Package ggmap
参考:ggmapで震源表示 - 迷途覚路夢中行 - Yahoo!ブログ
参考:ggmap チュートリアル (useR 2012)
参考:Rの基本グラフィックス機能またはggplot2を使って地図を描くには - verum ipsum factum

群別色つき箱ひげ図

ggplot(df, aes(x = factor(g), y = y)) +
  geom_boxplot(aes(fill = factor(h)), outlier.size = 3, position = position_dodge(width = 0.9))

集計データから棒グラフ

summaryd <- data.frame(x = c("A1", "B2", "C3", "D4"), y = c(10, 12, 43, 11))
ggplot(summaryd, aes(x, y)) + geom_bar(stat = "identity")

stat_function で任意の関数を重ねる

stat_function を使うと任意の関数をプロットできます。

rndf <- data.frame(x = rnorm(1000))
ggplot(rndf, aes(x, colour = 'Histogram')) +
  geom_histogram(aes(y = ..density..), show.legend = FALSE, binwidth = 0.5) +
  stat_function(fun = dnorm, aes(colour = 'Density')) +
  scale_colour_manual(name = 'Legend', values = c('black', 'red')) +
  labs(title = "Histogram with Overlay")

参考:Modify Legend using ggplot2 in R (ヒストグラム上に確率密度関数を重ね描きする)

stat_summary 関数で要約統計量などを追加する

stat_summary 関数は、引数 fun.yfun.data に関数を渡して、一部の定義済み関数 or 自分で定義した関数を用い、要約値や計算値などを描画できる便利な関数です。
ただし、fun.y や fun.data を自分で定義する場合は、返り値の名前を適切に (name が "y", "ymin", "ymax" になるように) 決めておく必要があります。

ggplot(mtcars, aes(cyl, am)) +
  stat_summary(fun.y = mean, geom = "point") +
  stat_summary(fun.data = "mean_cl_boot", geom = "errorbar", fun.args = list(conf.int = .95))

参考:How can one write a function to create custom error bars for use with ggplot2 ? (エラーバーの計算方法をカスタマイズ)

二つ以上の因子の組み合わせで色や記号などを区別する

interaction を利用します。

mtcars$gear <- factor(mtcars$gear)
mtcars$carb <- factor(mtcars$carb)
ggplot(mtcars, aes(hp, disp, shape = gear, colour = carb)) +
  geom_point() + 
  geom_line(aes(group = interaction(carb, gear)))

参考:grouping by two factors (geom_line)

異なる複数のグラフを一つの図に描画

base グラフの par(mfrow = c(1, 2)) に対応する様なグラフを描画したい場合は、gridExtra パッケージの grid.arrange が利用できます。

require("gridExtra")

gedf <- data.frame(x = (x <- rnorm(100)), y = rnorm(100, x), w = 1:100)
p1 <- ggplot(gedf,  aes(x, y)) + geom_line()
p2 <- ggplot(gedf,  aes(w, y)) + geom_line()

grid.arrange(p1, p2, ncol = 2)

参考:legend - Outputting a textplot and qplot in same pdf or png in r - Stack Overflow (表とグラフの同時描画)

棒グラフに数値を付加する

tmp <- c(150.3, 84.61, 31.45, 11.08, -0.19, -57.83, -88.63, -98.39)
dd <- data.frame(y = tmp, x = LETTERS[1:8])
ggplot(dd, aes(x, y)) +
  geom_bar(fill = "darkgrey", stat = "identity") + 
  labs(x = "Premium change", y = "Total Expected Profit") + 
  geom_text(aes(x, ifelse(y > 0, y + 5, y - 5), label = y), size = 4, colour = "black")

参考:plotting bar graphs in R using ggplot2 (Stack Overflow)

系列の番号等を表示する

directlabels package を用いると簡単に表示できます。

require("directlabels")
require("ggplot2")
data(BodyWeight, package = "nlme")
p <- qplot(Time, weight, data = BodyWeight, colour = Rat, geom = "line", facets = . ~ Diet)
direct.label(p, first.points)
direct.label(p, last.points)

ギリシャ文字や数式を含むラベルの作成

Plotmath · hadley/ggplot2 Wiki · GitHubr - How to use Greek symbols in ggplot2? - Stack Overflow が参考になります。

  • テキストラベル
    • parse = Tgeom_textannotate 中で利用
  • 軸ラベル
    • expression(alpha) を利用
  • Facet ラベル
    • labeller = label_parsedfacet 内で利用
  • 凡例ラベル
    • bquote(alpha == .(value)) を凡例ラベル内で利用

記事メモと予定

ggplot2 の改訂に関するメモ

2.0.0

追記等の記録

  • 2016/01/08 ggplot2 2.0.0 に関する改定を一通り終了
  • 2016/01/06 ggplot2 2.0.0 に関する改定を開始
  • 2016/01/05 ggplot2 2.0.0 に関する修正と内容の追加 (一部古すぎる情報を移動)
  • ...中略...
  • 2010/05/28 初版の記事を作成