## knitr configuration: http://yihui.name/knitr/options#chunk_options
opts_chunk$set(comment = "", error= TRUE, warning = FALSE, message = FALSE,
tidy = FALSE, cache = F, echo = T,
fig.width = 6, fig.height = 6)
## R configuration
options(width = 116, scipen = 5)
library(ggplot2)
ggplot2ではグラフの部品を組み合わせてグラフを描画する。具体的には下記の項目を指定してデータをグラフ化する。省略した文法も存在するが、あえていっさい省略せずに記述した方がggplot2の考え方がわかりやすい。
指定項目
付属のダイアモンドのデータを使用する。カラット数と値段の関係をダイアモンドの透明度ごとに図示する。
data(diamonds)
head(diamonds)
carat cut color clarity depth table price x y z
1 0.23 Ideal E SI2 61.5 55 326 3.95 3.98 2.43
2 0.21 Premium E SI1 59.8 61 326 3.89 3.84 2.31
3 0.23 Good E VS1 56.9 65 327 4.05 4.07 2.31
4 0.29 Premium I VS2 62.4 58 334 4.20 4.23 2.63
5 0.31 Good J SI2 63.3 58 335 4.34 4.35 2.75
6 0.24 Very Good J VVS2 62.8 57 336 3.94 3.96 2.48
最初にggplot()を使用してデータと変数の配置を設定する。これをp1と名付けて置くことで再利用できるようにする。このようにggplotのグラフの部品は個別にオブジェクトとして置いておくことができる。
p1 <- ggplot(data = diamonds,
mapping = aes(x = carat, y = price, color = clarity))
summary(p1)
data: carat, cut, color, clarity, depth, table, price, x, y, z [53940x10]
mapping: x = carat, y = price, colour = clarity
faceting: facet_null()
aes()という関数を通すことでggplot2が再利用できる形のmappingオブジェクトを作成して、mappingオプションに渡している。summary(p1)とすることでどのような指定がされているかをみることができる。
変数を配置できる項目には下記のようなものが存在する。グラフの種類によって必要ないものもある。ここではx, y, colorだけを使用している。
layer()を使って統計処理(stat)と形態(geom)を指定する。複雑なグラフでは複数のlayer()を重ねて描画する。ここまでで最低限の要素がそろうのでグラフとして出力可能になる。
l1 <- layer(stat = "identity",
geom = "point")
l1
geom_point:
stat_identity:
position_identity: (width = NULL, height = NULL)
l1として表示するとどのような指定をしているのかみることができる。さらに、グラフの構成要素を + でつないで実行するとグラフを実際に描画する。ループ内などではprint(p1 + l1)のようにする必要がある。
p1 + l1
重ね書きによく使われるのは分布の傾向を示すsmoother。サンプル数が少ない場合はloess (Local Polynomial Regression Fitting)が、サンプル数が多い場合はGAM (Generalized additive model)によるfittingが行われる。
stat_smooth(mapping = NULL, data = NULL, geom = "smooth",
position = "identity", method = "auto",
formula = y ~ x, se = TRUE, n = 80, fullrange = FALSE,
level = 0.95, na.rm = FALSE, ...)
smootherを重ねてみます。デフォルトではregressionで曲線を描くsmooth statと最適化された形態のsmooth geomの組み合わせです。colorによるグループ分けの影響を受けてしまうので、color = “blue”(カラー分けしないで一色指定)をいれています。このように定数を指定する場合はaes(color = var_name)のようなmapping = aes()は必要ないです。曲線と95%信頼区間が表示されます。
lsm1 <- layer(stat = "smooth",
geom = "smooth",
color = "blue")
p1 + l1 + lsm1
point lineを使うように強制すれば、曲線のみが描画されます(さっきのlayerにse = FALSEを与えても同じ結果になります)。
lsm2 <- layer(stat = "smooth",
geom = "line",
color = "blue")
p1 + l1 + lsm2
範囲を示すバンドを作成するribbon geomを強制してみます。下記のようなmappingを追加できます。
‘geom_ribbon’ understands the following aesthetics (required
aesthetics are in bold):
• ‘*x*’
• ‘*ymax*’
• ‘*ymin*’
• ‘alpha’
• ‘colour’
• ‘fill’
• ‘linetype’
• ‘size’
ここでは線を青、真ん中の塗りつぶしを薄青でかつalphaをつかって80%の不透明度(20%透明)にしてみます。
lsm3 <- layer(stat = "smooth",
geom = "ribbon",
color = "blue", fill = "lightblue", alpha = 4/5)
p1 + l1 + lsm3
ここで取り上げた例は実用性が微妙ですが、このように統計処理を示すstatとグラフの形態を指定するgeomを独立して扱うことにより、自在にグラフが作成できます。下記のサイトにより具体的な例が記載されています。
http://www.ling.upenn.edu/~joseff/avml2012/
geom_()やstat_()という部品をlayer()の代わりに使っていますが、これは省略した記載方法です。
X軸とY軸の変数が連続変数、color軸(?)の変数がカテゴリー変数になっている。このためそれぞれ、下記のような軸指定が使われているが、これを調節することが可能。これもオブジェクトして置いておいて再利用可能である。
X軸を細かく指定する。
sX <- scale_x_continuous(name = "C A R A T", # 軸の名前を変える
breaks = c(0,2,4), # 軸の区切りを0,2,4にする
labels = c("zero","two","four"), # 区切りを名付ける
limits = c(0,4)) # 0から4までしか表示しない
sX
continuous_scale(aesthetics = c("x", "xmin", "xmax", "xend",
"xintercept"), scale_name = "position_c", palette = identity,
name = "C A R A T", breaks = ..2, labels = ..3, limits = ..4,
expand = expand, guide = "none")
Y軸を細かく指定する。いじらない項目は指定しなくてよい。
sY <- scale_y_continuous(name = "price (log10 axis)", # 軸の名前を変える
breaks = c(500,1000,5000,10000,50000), # 区切り指定
trans = "log10") # 底10のlog変換軸とする
sY
continuous_scale(aesthetics = c("y", "ymin", "ymax", "yend",
"yintercept", "ymin_final", "ymax_final"), scale_name = "position_c",
palette = identity, name = "price (log10 axis)", breaks = ..2,
expand = expand, trans = "log10", guide = "none")
color軸を細かく指定する。
sC <- scale_color_discrete(breaks = rev(levels(diamonds$clarity)), # 配置順を逆
## 上から3つまでしか色を付けない。
limits = rev(levels(diamonds$clarity))[1:3],
## 下記はデフォルト
h = c(0, 360) + 15, # 色の範囲
c = 100, # 色の濃さ
l = 65, # 色の明るさ
h.start = 0, # 色の開始位置
direction = 1, # 色変化の向き
## 下記だけデフォルトgrey50から変更有り
na.value = "white") # 色無しの時の色
sC
discrete_scale(aesthetics = "colour", scale_name = "hue", palette = hue_pal(h,
c, l, h.start, direction), breaks = ..1, limits = ..2, na.value = na.value)
gridExtraパッケージのgrid.arrangeを使って軸をいじる前と後とで並べて表示する。
library(gridExtra)
grid.arrange(p1 + l1,
p1 + l1 + sX + sY + sC)
点が重なってわかりにくいので、clarityごとにグラフを分割する。最初に色の指定を上三つだけでなくすべて表示するように指定。
sC2 <- scale_color_discrete(breaks = rev(levels(diamonds$clarity)))
sC2
discrete_scale(aesthetics = "colour", scale_name = "hue", palette = hue_pal(h,
c, l, h.start, direction), breaks = ..1, na.value = na.value)
facet_grid(行分けの変数 ~ 列分けの変数)という形で指定する。指定しない時は.を使う。ここでは行方向にcutの品質で分割、列方向に透明度で分割してみる。
f1 <- facet_grid(cut ~ clarity)
f1
facet_grid(cut ~ clarity)
p1 + l1 + sX + sY + sC2 + f1
?themeで表示されるように、たくさん指定できる項目がある。項目ごとにelement_*()という関数を介してオプションを与えるようになっておりややこしい。
th1 <- theme(
## X軸のタイトルをピンクに
axis.title.x = element_text(color = "pink"),
## Y軸のタイトルをを太斜体に
axis.title.y = element_text(face = "bold.italic"),
## グラフの背景を白に
panel.background = element_rect(fill = "white"),
## グラフの背景の線を紫色に
panel.grid.major = element_line(color = "purple"),
## 凡例の点の後ろを黄色に
legend.key = element_rect(fill = "lightyellow")
)
p1 + l1 + th1
element_line()
colour: line colour
size: line size
linetype: line type
lineend: line end
color: an alias for ‘colour’
element_rect()
fill: fill colour
colour: border colour
size: border size
linetype: border linetype
color: an alias for ‘colour’
element_text()
family: font family
face: font face ("plain", "italic", "bold", "bold.italic")
colour: text colour
size: text size (in pts)
hjust: horizontal justification (in [0, 1])
vjust: vertical justification (in [0, 1])
angle: angle (in [0, 360])
lineheight: line height
color: an alias for ‘colour’
element_blank()は要素を空にするときに使う。