Mukku John Blog

取り組んでいること を つらつら と

ggplot2を使って、散布図を作る-1

R グラフィックス クックブック 10回目

ggplot2パッケージを利用して、散布図を作成していきます。

散布図 - Wikipedia

こんなデータです。

> head(heightweight[, c("ageYear","heightIn")])
  ageYear heightIn
1   11.92     56.3
2   12.92     62.3
3   12.75     63.3
4   13.42     59.0
5   15.92     62.5
6   14.25     62.5

> str(heightweight[, c("ageYear","heightIn")])
'data.frame':	236 obs. of  2 variables:
 $ ageYear : num  11.9 12.9 12.8 13.4 15.9 ...
 $ heightIn: num  56.3 62.3 63.3 59 62.5 62.5 59 56.5 62 53.8 ...

散布図は、geom_point()を使います。

(折れ線に点を付ける時に使いました。)
mukkujohn.hatenablog.com

ggplot(heightweight, aes(x=ageYear, y=heightIn)) +
  geom_point()

f:id:MukkuJohn:20160827213514p:plain
x軸:ageYear/y軸:heightInでマッピングし、観測点を点で図示しています。


点の形や大きさは、geom_point()で、shapeやsizeを指定します。

ggplot(heightweight, aes(x=ageYear, y=heightIn)) +
  geom_point(shape = 21)

f:id:MukkuJohn:20160827213952p:plain

ggplot(heightweight, aes(x=ageYear, y=heightIn)) +
  geom_point(size = 1.5)

f:id:MukkuJohn:20160827214021p:plain

離散値でグループ化する

グループ化に使う変数が、離散値の場合は、点の色・形で表現します。

色・形のエステティック属性に、
グループ化に使いたい変数をマッピングするだけです。


先ほどのデータに、性別を表す列が追加されたデータを使います。
sex列が、Factor=離散値になっていますね。

> head(heightweight[, c("ageYear","heightIn","sex")])
  ageYear heightIn sex
1   11.92     56.3   f
2   12.92     62.3   f
3   12.75     63.3   f
4   13.42     59.0   f
5   15.92     62.5   f
6   14.25     62.5   f

> str(heightweight[, c("ageYear","heightIn","sex")])
'data.frame':	236 obs. of  3 variables:
 $ ageYear : num  11.9 12.9 12.8 13.4 15.9 ...
 $ heightIn: num  56.3 62.3 63.3 59 62.5 62.5 59 56.5 62 53.8 ...
 $ sex     : Factor w/ 2 levels "f","m": 1 1 1 1 1 1 1 1 1 1 ...

点の色でグループ化をします。
マッピングする時に、colourを指定します。

ggplot(heightweight, aes(x=ageYear, y=heightIn, colour=sex)) +
  geom_point()

f:id:MukkuJohn:20160827214427p:plain

点の形でグループ化します。
マッピングする時に、shapeを指定します。

ggplot(heightweight, aes(x=ageYear, y=heightIn, shape=sex)) +
  geom_point()

f:id:MukkuJohn:20160827214524p:plain

グループ化するときに、点の色と形の両方を指定することもできます。

ggplot(heightweight, aes(x=ageYear, y=heightIn, shape=sex, colour=sex)) +
  geom_point()

f:id:MukkuJohn:20160827214638p:plain


グループ化を表している、色や形を変更したい場合は、
scale_shape_manual()や、scale_colour_brewer()を使います。

ggplot(heightweight, aes(x=ageYear, y=heightIn, shape=sex, colour=sex)) +
  geom_point() +
  scale_shape_manual(values = c(1,2)) +
  scale_colour_brewer(palette = "Set1")

f:id:MukkuJohn:20160827214857p:plain


点の形と色を別の変数で、図示する場合は、ややこしい手順を踏みます。
性別を形で、体重が100ポンド*1以上かどうかを色で表現します。
f:id:MukkuJohn:20160827221516p:plain

コードはこんな感じです。

#形は性別を、塗りつぶしは重さでグループ化する
ggplot(hw, aes(x = ageYear, y = heightIn, shape = sex, fill = weightGroup)) +
  geom_point(size = 2.5) +
#形は塗りつぶしができる形にすること
  scale_shape_manual(values = c(21, 24)) +
#塗りつぶし色を指定する
  scale_fill_manual(values = c("green", "pink"), 
#凡例は、塗りつぶしができる形を選ぶこと
                    guide = guide_legend(override.aes = list(shape = 22))) 

連続値でグループ化する

グループ化に使う変数が、連続値の場合は、点の色・大きさで表現します。

離散値でグループ化するのと同様に、
エステティック属性に、マッピングするだけです。


離散値でグループ化したデータに、重さを表す列が追加されたデータを使います。

> head(heightweight[, c("ageYear","heightIn","sex","weightLb")])
  ageYear heightIn sex weightLb
1   11.92     56.3   f     85.0
2   12.92     62.3   f    105.0
3   12.75     63.3   f    108.0
4   13.42     59.0   f     92.0
5   15.92     62.5   f    112.5
6   14.25     62.5   f    112.0

> str(heightweight[, c("ageYear","heightIn","sex","weightLb")])
'data.frame':	236 obs. of  4 variables:
 $ ageYear : num  11.9 12.9 12.8 13.4 15.9 ...
 $ heightIn: num  56.3 62.3 63.3 59 62.5 62.5 59 56.5 62 53.8 ...
 $ sex     : Factor w/ 2 levels "f","m": 1 1 1 1 1 1 1 1 1 1 ...
 $ weightLb: num  85 105 108 92 112 ...


点の色でグループ化をします。
マッピングする時に、colourを指定します。

ggplot(heightweight, aes(x = ageYear, y = heightIn, colour = weightLb)) +
  geom_point()

f:id:MukkuJohn:20160827222726p:plain


点の大きさでグループ化をします。
マッピングする時に、sizeを指定します。

ggplot(heightweight, aes(x = ageYear, y = heightIn, size = weightLb)) +
  geom_point()

f:id:MukkuJohn:20160827222814p:plain


色も大きさも、分かりづらいですね。
また、点の大きさが2倍くらいになっているからと言って、
データも2倍くらいになっているというわけではない事に注意ですね。


分かりづらさは、塗りつぶしのグラデーションを指定したり、
凡例を離散的にすることでカバーします。

塗りつぶし色のグラデーションを指定します

ggplot(heightweight, aes(x = weightLb, y = heightIn, fill = ageYear)) +
  geom_point(shape = 21, size = 2.5) +
  scale_fill_gradient(low = "black" , high = "white")

f:id:MukkuJohn:20160827223653p:plain


凡例を離散的にします

ggplot(heightweight, aes(x = weightLb, y = heightIn, fill = ageYear)) +
  geom_point(shape = 21, size = 2.5) +
  scale_fill_gradient(low = "black" , high = "white",
                      breaks = 12:17, guide = guide_legend())

f:id:MukkuJohn:20160827223804p:plain


こんな感じで、連続値を大きさに、離散値を色に指定することもできます。
(分かりづらい印象は残ったままですが。。。)

ggplot(heightweight, aes(x = ageYear, y = heightIn, size = weightLb, colour = sex)) +
  geom_point(alpha = .5) +
  scale_size_area() +
  scale_colour_brewer(palette = "Set1")

f:id:MukkuJohn:20160827224323p:plain


また、sizeを指定しているときは、shapeを指定するはやめましょう。
というのも、同じグループに属していても、形が違うと大小が分からないです。

ggplot(heightweight, aes(x = ageYear, y = heightIn, size = weightLb, shape = sex)) +
  geom_point() +
  scale_shape_manual(values = c(18, 19))

f:id:MukkuJohn:20160827225500p:plain

散布図は、棒グラフや折れ線グラフより、表現が豊かですね。
まぁそのぶん、上述したように、気を付けるポイントも多そうです。


次回は、点の数が多すぎるオーバープロットを扱います。

*1:1ポンド = 453.592グラム