Triad sou.

ggplot2 の自分用メモ集を作ろう (古い内容)

古い記事を移動しました。

基本プロットを作る

基本的な手順は、

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

の二つが分かっていれば OK です。
これに加えて、統計処理をしてくれる stat_XXX() やラベルや凡例などのその他の細かいオプションを指定できます。

require(ggplot2)
df <- data.frame(
  x  = (x  <- rnorm(100)),
  y  = (y  <- rnorm(100, x)),
  zx = (zx <- (rep(1:10, 10) - 5) / 2),
  zy = (zy <- (rep(1:10, each=10) - 5) / 2),
  z  = (z  <- zx*zy),
  w  = 1:100,
  g  = rep(1:2, 50),
  h  = c(rep(1, 50), rep(2, 50))
)
sdf <- subset(df, w <= 10)

p1 <- ggplot(df,  aes(x = x, y = y)) + geom_line()
p2 <- ggplot(df,  aes(x = w, y = y)) + geom_line()
p  <- ggplot(df,  aes(x = x, y = y, colour = factor(g))) + geom_line()
q  <- ggplot(sdf, aes(x = factor(w), y = y)) + geom_bar(stat = "identity")
r  <- ggplot(df,  aes(x = x, y = ..density..)) + geom_histogram()
c  <- ggplot(df,  aes(x = zx, y = zy, z = z)) + geom_contour()

プロットタイプ geom, stat
p1: 散布図型 普通の散布図 (geom_point, geom_jitter)
折れ線 (geom_line)
階段 (geom_step)
リアプロット (geom_area)
スムージング (geom_smooth)
四角形を隙間無くプロット (geom_bin2d, stat_bin2d)
六角形を隙間無くプロット (geom_hex, stat_binhex)
装飾 (geom_quantile, stat_quantile, geom_ribbon, stat_smooth)
p: 散布図型 上+複数グループデータ、凡例や色セットも見るべし
q: 横軸離散値 箱ヒゲ図 (geom_boxplot, stat_boxplot)
Dot プロット (geom_dotplot)
Violin プロット (geom_violin)
High-Low プロット (geom_crossbar)
棒グラフ (geom_bar)
範囲プロット (geom_linerange)
範囲 + 代表値プロット (geom_pointrange)
平均ヒゲ (geom_errorbar)
横向き平均ヒゲ (geom_errorbarh)
r: ヒストグラム ヒストグラム (geom_histogram, stat_bin)
折れ線ヒストグラム (geom_freqpoly)
密度推定 (geom_density, stat_density)
c: 等高線型 等高線 (geom_contour, stat_contour, geom_density2d, stat_density2d)
密度の塗り分け (geom_tile)
geom_tile の仲間 (geom_raster)
その他 一次元散布図の追加 (geom_rug)
任意の直線 (geom_abline, stat_abline)
横軸参照線 (geom_hline, stat_hline)
縦軸参照線 (geom_vline, stat_vline)
一筆書き (geom_path)
map プロット (geom_map)
ポリゴン塗りつぶし (geom_polygon)
四角形塗りつぶし (geom_rect)
文字列の描画 (geom_text)
矢印等の追加 (geom_segment, stat_spoke)
何もプロットしない (geom_blank)
stat 任意の関数 (stat_function)
Q-Qプロット (stat_qq)
基本的には ggplot() でデータ構造を指定し、geom_XXX()stat_XXX() でグラフの種類や処理の種類を指定することによって描画します。
もっと簡単にグラフを作りたい! → 簡易版の qplot() を使います。

aes

aes のパラメータのリストです。

adj,  alpha,  angle,  bg,  cex,  col,  color,  colour,
fg,  fill,  group,  hjust,  label,  linetype,  lower,
lty,  lwd,  max,  middle,  min,  order,  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,

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

層別したグラフを並べる

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

p + facet_wrap( ~ g, nrow = 2, ncol = 1)
p + facet_grid(. ~ g)
p + facet_grid(g ~ .)

層別したい因子が二次元の場合は

p + facet_grid(g ~ h)

さらに、軸スケールをグラフごとに変更したい場合

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

が利用できる。

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

map プロット

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

geom_XXX() 系関数でデータ (フレーム) を指定しない場合、ggplot() で指定したデータが自動的に使われる。
データも異なる場合、2つ目以降の geom_XXX() 等に data = YYYaes() を付ける。

r + geom_histogram(binwidth = 1) +
    geom_line(data = mydata2, aes(x = X, y = Y), colour = "#3B4FB8", size = 1.5)

参照線の追加

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

p + geom_vline(xintercept = c(-1, 1), linetype = "dotted")

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

p + xlab("axis.x.label")
p + ylab("axis.y.label")
p + labs(x = "axis.x.label", y = "axis.y.label")

タイトルは

# 0.9.2 以降 (opts は廃止予定)
p + ggtitle("OPTS TITLE")

# 0.9.1 まで
p + opts(title = "OPTS TITLE")

おまけ、

# 軸ラベルとタイトルの一括指定
p + labs(title = "OPTS TITLE", x = "axis.x.label", y = "axis.y.label")

軸の表示範囲を変更する

p + xlim(-1, 1)
p + ylim(-3, 3)
q + xlim("1", "2", "3")

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

p + scale_x_continuous(expand = c(0, 0))
p + scale_y_continuous(expand = c(0, 0))
q + scale_x_discrete(expand = c(0, 0))
q + scale_y_discrete(expand = c(0, 0))

軸区切り値の変更

任意の区切り、任意の表示が可能になります。

p + scale_x_continuous(
  breaks = seq(1, 8, by = 1),
  labels = c("1st", "2nd", "3rd", "4th", "5th", "6th", "7th", "8th")
)
q + scale_x_discrete(
  breaks = seq(0, 1, by = 1),
  labels = c(expression(a <= 10), expression(a > 10))
)

軸スケールの変更 (変数変換)

p2 + coord_trans(x = "log10")

または、

p2 + scale_x_log10()
p2 + scale_x_continuous(trans = "log10")

などがある。


他にも、変換できそうなキーワード (未チェック)

asn, atanh, exp, inverse, log, log10, log1p, log2, logit, pow, pow10, probit, recip, reverse, sqrt
date, datetime, prob

などがある。

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

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

基本的にはデータフレームを編集し、factor 型の変数の levels を並べ替えます。

scale

ggplot2 には様々なスケールが定義されており、プロット時のグループ表示や、プロットの塗り分けに使うスケールや、軸の設定に使うスケールがあります。

scale タイプ 説明
scale_linetype グループ表示 線種によるスケールを使う
scale_shape グループ表示 記号によるスケールを使う
scale_size グループ表示 ドットの大きさによるスケールを使う
scale_grey グループ表示 グレーの色スケールを使う
scale_gradient グループ表示 2色のグラデーションの色スケールを使う
scale_gradient2 グループ表示 3色のグラデーションの色スケールを使う
scale_gradientn グループ表示 n色のグラデーションの色スケールを使う
scale_hue グループ表示 虹色のグラデーションの色スケールを使う
scale_brewer グループ表示 定義された色スケールを使う (colorbrewer.org)
scale_alpha グループ表示 不透明度の色スケールを使う
scale_manual グループ表示 任意の離散スケールを使う
scale_identity グループ表示 スケールを変更しない
scale_discrete 任意の離散値軸スケールを作る
scale_continuous 任意の連続値軸スケールを作る
scale_date 年月日軸スケールを作る
scale_datetime 年月日時間軸スケールを作る

凡例位置の変更

# 0.9.2 以降 (opts は廃止予定)
p + theme(legend.position = c(0.95, 0.05), legend.justification = c(1, 0))
p + theme(legend.position = "top")
p + theme(legend.position = "right")
p + theme(legend.position = "bottom")
p + theme(legend.position = "left")
p + theme(legend.position = "none")


# 0.9.1 まで
p + opts(legend.position = c(0.95, 0.05), legend.justification = c(1, 0))
p + opts(legend.position = "top")
p + opts(legend.position = "right")
p + opts(legend.position = "bottom")
p + opts(legend.position = "left")
p + opts(legend.position = "none")

凡例ラベルの変更

scale_XXX_YYY()labs() を使う。

p + scale_colour_discrete("ラベル変更")
p + labs(colour = "ラベル変更")

fill, colour, shape など、凡例を生成する複数の aes を設定している場合、labs を使うことで全ての凡例を重ねて表示できる。

p + labs(fill = "同じラベル", colour = "同じラベル", shape = "同じラベル")

凡例の一部を削除する

基本のプロットに加えて、geom_text() で文字列を追加しようとすると、凡例に文字が追加される。
これを消したい場合、show_guide = FALSE オプションを入れればよい。

# 0.9.1 以降
p + geom_text(data = data, aes(y = y, x = x, label = label), show_guide = FALSE)

# 0.8.9 まで
p + geom_text(data = data, aes(y = y, x = x, label = label), legend = FALSE)

他にも geom_line()geom_point() を使って、凡例は線だけにしたい場合などに利用できる。

色セットの変更

プロットで描画される線や点の色は、色セットで定義されています。
RColorBrewer package で定義されている色セットを使って、グループ別に色を塗り分けます。

p + scale_color_brewer(palette = "Pastel1")
q + scale_fill_brewer(palette = "Pastel1")

scale についての説明も参照してください。


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

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

任意の色セットの利用

ggplot2 package でカラーパターンの変更
ついでに凡例ラベルの変更もできる。

colours <- c("#D92121", "#9999FF", "#D92121", "#21D921", "#FFFF4D", "#FF9326")
p + scale_colour_manual("Group", value = colours)

定義済み theme の適用と編集

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

p + theme_bw()
p + theme_gray()
p + theme_classic()
p + theme_minimal()

このようになります。


ggplot2-0.9.3 では、

  • theme_bw()
  • theme_grey(), theme_gray()
  • theme_classic()
  • theme_minimal()

が利用できます。


デフォルトで使用するテーマを設定しておくこともできる

theme_set(theme_bw())

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

theme_get()

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

theme_bw


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

# 0.9.2 以降 (theme_xx は element_xx に置換され、上位の要素が継承されるようになった)
my_theme_bw <- function (base_size = 25, 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-ing up (ggplot2 google group) を参考に modifyList を使って定義を変更すると (axis.text.x の vjust = 0.5 に変更してみた例)

# 0.9.1 まで
my_theme_bw <- function (base_size = 25, base_family = "") {

  mod <- list(
    axis.text.x = theme_text(family = base_family, size = base_size * 0.8,
    lineheight = 0.9, vjust = 0.5)
  )
  modifyList(theme_bw(base_size = base_size, base_family = base_family), mod)

}
ggthemes package

GitHub - jrnold/ggthemes: Additional themes, scales, and geoms for ggplot2

  • 追加 theme (Tufte minimal ink theme, Solarized, Stata themes, The Economist, Excel)
  • 追加 geom (Tufte range frame, Tufte box plot)
  • 追加 scale (主に色関係)
現在のテーマをバックアップしておいて、一部分だけ変更した後にグラフを描画して元に戻す場合。
theme_set(theme_gray())
old <- theme_update(panel.background = element_rect(colour = "pink"))
p
theme_set(old)

element_xx() 関数と theme() 関数 (theme_xx() 関数と opts() 関数)

注:0.9.2 からは、theme_xx()element_xx() に、opts()theme() へと変更されていますので、0.9.1 までを利用されている場合は theme_xx()opts() に読み替えてください。


theme 要素の設定を変更すると、フォント、太字やイタリック、色、サイズ、マージン、縦横揃え、向き、一行の高さ、線種、塗りつぶしの設定を行うことができます。
theme 要素の一部を以下に示しました。

theme の要素 タイプ 説明
axis .line element_line 軸の線
.line.x element_line x 軸の線の個別指定 (0.9.2 以降)
.line.y element_line y 軸の線の個別指定 (0.9.2 以降)
.text.x element_text x 軸の目盛り線の数値や文字
.text.y element_text y 軸の目盛り線の数値や文字
.ticks element_line 軸の目盛り線
.ticks.x element_line x 軸の目盛り線の個別指定 (0.9.2 以降)
.ticks.y element_line y 軸の目盛り線の個別指定 (0.9.2 以降)
.ticks.length unit 軸の目盛り線の長さ
.ticks.margin unit 軸の目盛り線と数値間のマージン
.title.x element_text x 軸のラベル
.title.y element_text y 軸のラベル
legend .background element_rect 凡例の背景
.margin unit 凡例のマージン
.key element_rect 凡例要素の背景
.key.size unit 凡例要素の縦横幅
.key.height unit 凡例要素の縦幅
.key.width unit 凡例要素の横幅
.text element_text 凡例要素のラベル
.title element_text 凡例のタイトル
.position 特殊 凡例の位置 ("top", "bottom", "right", "left", c(x, x))
.direction 特殊 凡例値の配置方向 ("vertical", "horizontal")
.justification 特殊 凡例の揃え位置 (c(x, x))
.box 特殊 複数凡例の配置方向 ("vertical", "horizontal")
.text.align 特殊 凡例要素の揃え方 (0, 1)
.title.align 特殊 凡例のタイトルの揃え方 (0, 1)
panel .background element_rect パネルの背景
.border element_rect パネルのボーダー
.grid.major element_line グリッド線
.grid.major.x element_line x 軸のグリッド線の個別指定 (0.9.2 以降)
.grid.major.y element_line y 軸のグリッド線の個別指定 (0.9.2 以降)
.grid.minor element_line 補助グリッド線
.grid.minor.x element_line x 軸の補助グリッド線の個別指定 (0.9.2 以降)
.grid.minor.y element_line y 軸の補助グリッド線の個別指定 (0.9.2 以降)
.margin unit パネルのマージン
strip .background element_rect 層別プロット時の層ラベルの背景
.text.x element_text 層別プロット時のx軸の数値や文字
.text.y element_text 層別プロット時のy軸の数値や文字
plot .background element_rect グラフの背景
.title element_text グラフのタイトル
.margin unit グラフの枠とパネル間のマージン
theme_bw() などの定義を参考に自分で theme を作成しても良いですし、theme() 関数を使って一部を変更することもできます。

element_text タイプの要素

family, face, colour, size, hjust, vjust, angle および lineheight を設定できます。

# 0.9.2 以降
p + ggtitle("TITLE") + theme(plot.title = element_text(size = 20, face = "italic"))

# 0.9.1 まで
p + opts(title = "OPTS TITLE", plot.title = theme_text(size = 20, face = "italic"))
element_rect タイプの要素

fill (塗りつぶしの色), colour (枠線), size および linetype を設定できます。

# 0.9.2 以降
p + theme(plot.background = element_rect(fill = "grey80", colour = NA))

# 0.9.1 まで
p + opts(plot.background = theme_rect(fill = "grey80", colour = NA))
element_line タイプの要素

colour, size および linetype を設定できます。

# 0.9.2 以降
p + theme(panel.grid.major = element_line(colour = "red"))

# 0.9.1 まで
p + opts(panel.grid.major = theme_line(colour = "red"))

theme_line()theme_segment()element_line() に統合されました。

unit タイプの要素

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

# 0.9.2 以降
p + theme(plot.margin = unit(c(0.5, 0.5, 0.5, 0.5), "cm"))

# 0.9.1 まで
p + opts(plot.margin = unit(c(0.5, 0.5, 0.5, 0.5), "cm"))

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

element_blank()

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

# 0.9.2 以降
p + theme(panel.grid.minor = element_blank())

# 0.9.1 まで
p + opts(panel.grid.minor = theme_blank())

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

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

# 0.9.2 以降
p + theme_bw() + theme(panel.grid.major = element_line(colour = "red"))

# 0.9.1 まで
p + theme_bw() + opts(panel.grid.major = theme_line(colour = "red"))

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

# 0.9.2 以降
p + theme(panel.grid.major = element_line(colour = "red")) + theme_bw()

# 0.9.1 まで
p + opts(panel.grid.major = theme_line(colour = "red")) + theme_bw()

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

ggsave 関数は、拡張子指定していればファイル形式を自動判別してくれる。

ggsave(paste0(path, "save1.png"), p, width = 10, height = 10)
ggsave(paste0(path, "save1.pdf"), p)

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

PDF や EPS で出力すると日本語が文字化けする場合

群別色つき箱ひげ図

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

集計データから棒グラフ

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

異なる複数のグラフを一つの図に描画 (gridExtra::grid.arrange)

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

require(ggplot2)
require(gridExtra)

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

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

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

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

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

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

plotting bar graphs in R using ggplot2 (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 = x, y = y)) +
  geom_bar(fill = "darkgrey") + 
  labs(x = "Premium change", y = "Total Expected Profit") + 
  geom_text(aes(x = x, y = ifelse(y > 0, y + 5, y - 5), label = y), size = 4, colour = "black")

系列の番号等を表示する

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)

stat_function で任意の関数を重ねる

stat_function を使うと任意の関数をプロットできますが、これを応用して、Modify Legend using ggplot2 in R (Stack Overflow) のように、ヒストグラム上に確率密度関数を重ね描きする事ができます。

# 0.9.2 以降
ggplot(data.frame(x = rnorm(1000)), aes(x = x, colour = 'Histogram')) +
  geom_histogram(aes(y = ..density..), 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")


# 0.9.1 まで
ggplot(data.frame(x = rnorm(1000)), aes(x = x, colour = 'Histogram')) +
  geom_histogram(aes(y = ..density..), legend = FALSE, binwidth = 0.5) +
  stat_function(fun = dnorm, aes(colour = 'Density')) +
  scale_colour_manual(name = 'Legend', values = c('black', 'red')) +
  opts(title = "Histogram with Overlay")

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

stat_summary 関数は、引数 fun.yfun.data に関数を渡して、一部の定義済み関数 or 自分で定義した関数を用い、要約値や計算値などを描画できる便利な関数です。
ただし、fun.y や fun.data を自分で定義する場合は、返り値の名前を適切に (name が "y", "ymin", "ymax" になるように) 決めておく必要があります。
How can one write a function to create custom error bars for use with ggplot2 ? (Stack Overflow) では、エラーバーの計算方法をカスタマイズするために利用しています。

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

二つ以上の因子で色や記号などを区別する

interaction() を利用します。grouping by two factors (geom_line)

mtcars$gear = factor(mtcars$gear)
mtcars$carb = factor(mtcars$carb)

ggplot(mtcars, aes(x = hp, y = disp, shape = gear, colour = carb)) +
    geom_point() + 
    geom_line(aes(group = interaction(carb, gear)))

日本語の ggplot2 情報

GUI-frontend

ggplot2の変更点、気になった点など

0.9.3
  • plotmatrix が deprecated になった。GGallyggpairs() 、または 私のパッケージ でも散布図行列を作画できます (plotmatrix の縦軸スケールが変なのでそれを修正し、色分けを追加したものを実装しています)。
  • could not find function "revalue" というエラーが表示される場合は、おそらく plyr が古いため update.packages() を実行すると良いかもしれません。
  • theme_minimal, theme_classic が追加
0.9.2
  • 0.9.2 では、theme_xx()element_xx()opts()theme() に変更されているので注意しよう (動きますが警告が表示されます)。
0.9.x

気になった変更・機能追加は、

  • NAMESPACE や依存関係の変更、require(scales), require(grid) などが必要になる場合があるので注意が必要そう
  • geom_dotplot の追加
  • geom_violin の追加
  • geom_map の追加
  • geom_raster の追加
  • geom_textfontfamily, fontface, lineheight が指定できるようになった。
  • annotation_custom の追加
  • scalelabels オプション (comma_format, dollar_format, percent_format, scientific_format, parse_format, math_format); 簡単に軸表示を修飾できる
library(scales)
p + scale_y_continuous(labels = percent)
p + scale_y_continuous(labels = dollar)
p + scale_x_continuous(labels = math_format(alpha + frac(1, .x)))

追記等の記録