Mukku John Blog

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

ggplot2パッケージを使って、棒グラフを作成してみる-2

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

ggplot2パッケージを利用して、棒グラフを作成していきます。

正負で色を塗り分ける

グラフ映えするデータセットを探すor作るのがメンドクサクなってきたので甘えます。

library(gcookbook)

このデータを利用します。

> head(climate)
    Source Year Anomaly1y Anomaly5y Anomaly10y Unc10y
1 Berkeley 1800        NA        NA     -0.435  0.505
2 Berkeley 1801        NA        NA     -0.453  0.493
3 Berkeley 1802        NA        NA     -0.460  0.486
4 Berkeley 1803        NA        NA     -0.493  0.489
5 Berkeley 1804        NA        NA     -0.536  0.483
6 Berkeley 1805        NA        NA     -0.541  0.475

このデータセットから条件に該当するサブセットを作ります。

> csub <- subset(climate,Source=="Berkeley" & Year >= 1900)
> head(csub)
      Source Year Anomaly1y Anomaly5y Anomaly10y Unc10y
101 Berkeley 1900        NA        NA     -0.171  0.108
102 Berkeley 1901        NA        NA     -0.162  0.109
103 Berkeley 1902        NA        NA     -0.177  0.108
104 Berkeley 1903        NA        NA     -0.199  0.104
105 Berkeley 1904        NA        NA     -0.223  0.105
106 Berkeley 1905        NA        NA     -0.241  0.107

正負を表す列を追加します。

> head(csub)
      Source Year Anomaly1y Anomaly5y Anomaly10y Unc10y   pos
101 Berkeley 1900        NA        NA     -0.171  0.108 FALSE
102 Berkeley 1901        NA        NA     -0.162  0.109 FALSE
103 Berkeley 1902        NA        NA     -0.177  0.108 FALSE
104 Berkeley 1903        NA        NA     -0.199  0.104 FALSE
105 Berkeley 1904        NA        NA     -0.223  0.105 FALSE
106 Berkeley 1905        NA        NA     -0.241  0.107 FALSE

これをグラフにします。

#マッピングして
> csubMap <- ggplot(csub,aes(x=Year,y=Anomaly10y,fill=pos))
#棒グラフを指定して
> barGraph <- geom_bar(stat = "identity", position = "identity")
#マッピングを棒グラフで描画する
> csubMap + barGraph

f:id:MukkuJohn:20160818203945p:plain

まず、この棒グラフの棒に枠線を指定してみます。

#棒グラフに枠線を付ける 枠線の色は黒、太さは0.25
> barGraphWithFrame <- geom_bar(stat = "identity", position = "identity", colour = "black", size = 0.25)
#マッピングを棒グラフで描画する
> csubMap + barGraphWithFrame

f:id:MukkuJohn:20160818204433p:plain

次に、この棒グラフの塗りつぶし色を変更してみます。

#見た目を指定する
> visualEffect <- scale_fill_manual(values = c("#CCEEFF","#FFDDDD"))
#マッピングを棒グラフで描画して、見た目を指定する
> csubMap + barGraphWithFrame + visualEffect

f:id:MukkuJohn:20160818204809p:plain

凡例が気に入らないで表示させないようにします。

#ガイド表示を無くす
> visualEffectNoGuide <- scale_fill_manual(values = c("#CCEEFF","#FFDDDD"), guide = FALSE)
#マッピングを棒グラフで描画して、見た目を指定する
> csubMap + barGraphWithFrame + visualEffectNoGuide

f:id:MukkuJohn:20160818205032p:plain

棒の幅と間隔を調整する

こんなデータセットを利用します。

> str(pg_mean)
'data.frame':	3 obs. of  2 variables:
 $ group : Factor w/ 3 levels "ctrl","trt1",..: 1 2 3
 $ weight: num  5.03 4.66 5.53
> head(pg_mean)
  group weight
1  ctrl  5.032
2  trt1  4.661
3  trt2  5.526
#データをマッピングする
> pgMap <- ggplot(pg_mean, aes(x=group,y=weight))
#棒グラフを指定する
> barGraph <- geom_bar(stat = "identity")
#マッピングを棒グラフで描画する
> pgMap + barGraph

f:id:MukkuJohn:20160818205328p:plain
これが指定なしの状態です。

幅を狭くします。

#幅を指定して、棒グラフを指定する
> narrowBarGraph <- geom_bar(stat = "identity", width = 0.5)
#マッピングを、幅を狭くした棒グラフで描画する
> pgMap + narrowBarGraph

f:id:MukkuJohn:20160818205645p:plain

幅を広くします

#幅を指定して、棒グラフを指定する
> wideBarGraph <- geom_bar(stat = "identity", width = 1)
#マッピングを、幅を広くした棒グラフで描画する
> pgMap + wideBarGraph

f:id:MukkuJohn:20160818205839p:plain

幅指定のデフォルト値は0.9でした。

#幅を指定して、棒グラフを指定する
>defaultBarGraph <- geom_bar(stat = "identity", width = 0.9)
#マッピングを、幅を指定した棒グラフで描画する
>pgMap + defaultBarGraph

f:id:MukkuJohn:20160818210222p:plain

グループ化された棒グラフの幅と間隔を調整する

こんなデータセットを利用します。

> str(cabbage_exp)
'data.frame':	6 obs. of  6 variables:
 $ Cultivar: Factor w/ 2 levels "c39","c52": 1 1 1 2 2 2
 $ Date    : Factor w/ 3 levels "d16","d20","d21": 1 2 3 1 2 3
 $ Weight  : num  3.18 2.8 2.74 2.26 3.11 1.47
 $ sd      : num  0.957 0.279 0.983 0.445 0.791 ...
 $ n       : int  10 10 10 10 10 10
 $ se      : num  0.3025 0.0882 0.311 0.1408 0.2501 ...
> head(cabbage_exp)
  Cultivar Date Weight        sd  n         se
1      c39  d16   3.18 0.9566144 10 0.30250803
2      c39  d20   2.80 0.2788867 10 0.08819171
3      c39  d21   2.74 0.9834181 10 0.31098410
4      c52  d16   2.26 0.4452215 10 0.14079141
5      c52  d20   3.11 0.7908505 10 0.25008887
6      c52  d21   1.47 0.2110819 10 0.06674995

データのマッピングを行います。

> cabbageMap <- ggplot(cabbage_exp, aes(x=Date,y=Weight,fill=Cultivar))

棒グラフを指定します。

#デフォルトの指定方法
> barGarph <- geom_bar(stat="identity",position = "dodge")
#幅指定付きの棒グラフ
> widthBarGraph <- geom_bar(stat="identity",width=0.5,position = "dodge")

デフォルト幅のグループ化された棒グラフを作成します。

> cabbageMap + barGraph

f:id:MukkuJohn:20160818211116p:plain

幅指定付きのグループ化された棒グラフを作成します。

> cabbageMap + widthBarGarph

f:id:MukkuJohn:20160818211201p:plain
こちらも、widthのデフォルト値は0.9です。

積み上げ棒グラフ

上のグラフを例にしますと、下記x軸の3カテゴリに対し

  • d16
  • d20
  • d21

それぞれ、c39とc52の2カテゴリが表示されていますが、
このc39とc52を横ではなく、上に積み上げて表示したものが、積み上げ棒グラフです。

指定方法は、こちらです。

geom_bar(stat="identity")

…グループ化された棒グラフの指定から、position="dodge"を取っただけです。
なので、今まで振れてきたグループ化された棒グラフは
わざわざカテゴライズされた値を横によけていたと解釈できます。

グラフはこちら。(上で作成したcabbageMapオブジェクトを利用します。)

> cabbageMap + buildupBarGraph

f:id:MukkuJohn:20160818212523p:plain
凡例の並びが逆なので、直します。

#凡例の並びを逆にする
> exNote <- guides(fill=guide_legend(reverse = TRUE))
#マッピングを積み上げ棒グラフで、凡例の並びを逆で描画する
> cabbageMap + buildupBarGraph + exNote

f:id:MukkuJohn:20160818212807p:plain
ちゃんと緑が上になりました。

積み上がり方の並び順を変えるには、マッピングを変更します。

#descを使用するために必要
> library(plyr) 
#マッピング時にorderを指定する。plyrのdesc関数を利用する
> cabbageMapDesc <- ggplot(cabbage_exp, aes(x=Date,y=Weight,fill=Cultivar,order=desc(Cultivar)))
#並び順が指定されたマッピングを、積み上げ棒グラフで描画する
> cabbageMapDesc + buildupBarGraph

f:id:MukkuJohn:20160818213204p:plain
積み上がるデータの順が、逆になりました。

この積み上げ棒グラフの見た目を変更します。

#棒に黒い線を付与する
> buildupBarGraphWithFrame <- geom_bar(stat = "identity",colour = "black")
#見た目にパステルカラーパレット
> visualEffect <- scale_fill_brewer(palette = "Pastel1")
#マッピングを、黒い枠線の積み上げ棒グラフで、凡例の並びを逆で、見た目をパステル描画
> cabbageMap + buildupBarGraphWithFrame + exNote + visualEffect

f:id:MukkuJohn:20160818213550p:plain

100%積み上げ棒グラフを作成する

各棒のy軸がパーセントで構成された棒グラフです。
x軸の各カテゴリ内で100%になる様に構成されています。
つまり、カテゴリ内で100%になるよう算出された列をマッピングするだけです。

カテゴリ内での算出を楽に行えるパッケージを利用します。

library(plyr)

今扱っているggplot2パッケージの作者が作成したパッケージです。

上のcabbageMapのグラフは、x軸がDate列の値毎に描画されているので、
Date値で分割して、重さのパーセンテージを計算して、
新しい列を追加したデータフレームを作ります。

ce <- ddply(cabbage_exp, "Date", transform, percent_weight = Weight / sum(Weight) * 100)

それぞれのデータフレームを比較するとこんな感じ

> head(cabbage_exp)
  Cultivar Date Weight        sd  n         se
1      c39  d16   3.18 0.9566144 10 0.30250803
2      c39  d20   2.80 0.2788867 10 0.08819171
3      c39  d21   2.74 0.9834181 10 0.31098410
4      c52  d16   2.26 0.4452215 10 0.14079141
5      c52  d20   3.11 0.7908505 10 0.25008887
6      c52  d21   1.47 0.2110819 10 0.06674995
> head(ce)
  Cultivar Date Weight        sd  n         se percent_weight
1      c39  d16   3.18 0.9566144 10 0.30250803       58.45588
2      c52  d16   2.26 0.4452215 10 0.14079141       41.54412
3      c39  d20   2.80 0.2788867 10 0.08819171       47.37733
4      c52  d20   3.11 0.7908505 10 0.25008887       52.62267
5      c39  d21   2.74 0.9834181 10 0.31098410       65.08314
6      c52  d21   1.47 0.2110819 10 0.06674995       34.91686

マッピングを変更します。

> cabbagePerMap <- ggplot(ce, aes(x=Date,y=percent_weight,fill=Cultivar))

あとは、上の積み上げ棒グラフで使ったこれらがそのまま使えます。

  • 幾何オブジェクトの指定
  • 凡例の指定
  • 見た目の指定
> cabbagePerMap + buildupBarGraphWithFrame + exNote + visualEffect

f:id:MukkuJohn:20160818215344p:plain

次回は、グラフ内にラベルを追加するのとクリープランドのドットプロットを
扱い、棒グラフはおしまいにしようと思います。