ggplot2を使って、注釈を入れる-2
R グラフィックス クックブック 21回目
ggplot2パッケージを利用して、図内に注釈を入れます。
前回の記事で、annotate()を使ってテキストや線分、網掛けや
gridパッケージを使って矢印を、図内にプロットしました。
mukkujohn.hatenablog.com
今回は、色をあえて変えることでの強調表示やエラーバー - Wikipediaを扱います。
強調表示
こちらのデータセットを使います。
R: Results from an Experiment on Plant Growth
> str(PlantGrowth) 'data.frame': 30 obs. of 2 variables: $ weight: num 4.17 5.58 5.18 6.11 4.5 4.61 5.17 4.53 5.33 5.14 ... $ group : Factor w/ 3 levels "ctrl","trt1",..: 1 1 1 1 1 1 1 1 1 1 ...
強調表示を行う下準備として、group列の値が"trt1"である事を示す列を追加します。
pg <- PlantGrowth pg$h1 <- "no" pg$h1[pg$group=="trt1"] <- "yes" > str(pg) 'data.frame': 30 obs. of 3 variables: $ weight: num 4.17 5.58 5.18 6.11 4.5 4.61 5.17 4.53 5.33 5.14 ... $ group : Factor w/ 3 levels "ctrl","trt1",..: 1 1 1 1 1 1 1 1 1 1 ... $ h1 : chr "no" "no" "no" "no" ...
h1列でグループ化した箱ひげ図をプロットします。
p <- ggplot(pg,aes(x=group,y=weight,fill=h1)) + geom_boxplot() p
このグラフですと、どのグループの箱を見れば良いか分かりません。
そこであえて、塗りつぶしの色を手動で設定することで、
目につく箱を指定します。
手動で塗りつぶし色を指定するためには、scale_fill_manual()を使います。
#yes or no の2つの値であるh1をfillにマッピングしているため、 #塗りつぶし色も2色を指定する p + scale_fill_manual(values=c("grey85","#FFDDCC"))
3levelsのgroup列をfillにマッピングした場合は、
scale_fill_manual()で3色指定します。
ggplot(PlantGrowth,aes(x=group,y=weight,fill=group)) + geom_boxplot() + scale_fill_manual(values=c("grey85","lightblue","#FFDDCC"))
levels数より多く指定しても、多い部分は無視されて図がプロットされます。
逆にlevels数に満たない場合はエラーになります。
Error: Insufficient values in manual scale. 3 needed but only 1 provided.
エラーバー
こちらのデータから、Cultivarがc39であるデータセットを使います。
> 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 ...
subset()を使って、条件に合致するデータだけ選択・取得します。
ce <- subset(cabbage_exp, Cultivar == "c39")
棒グラフを作成します。
ggplot(ce, aes(x=Date,y=Weight)) + geom_bar(fill="white",colour="black",stat = "identity")
上のグラフにエラーバーを追加しますが、
データセット内に、平均の標準偏差であるse列があるため、
この値を、geom_errorbar()を使って、追加します。
#y軸に対して、開始値:ymin~終了値:ymaxとして指定します。 #widthは、エラーバーの幅です。良さげな値を模索して指定します。 上のグラフ + geom_errorbar(aes(ymin=Weight-se,ymax=Weight+se),width=.2)
折れ線グラフでも同様です。
#折れ線→マーク→エラーバーの順でプロットしてます。 ggplot(ce, aes(x=Date,y=Weight)) + geom_line(aes(group=1)) + geom_point(size=4) + geom_errorbar(aes(ymin=Weight-se,ymax=Weight+se),width=.2)
このエラーバーですが、グループ化された棒グラフや折れ線グラフの場合、
pisitionを横にずらす必要があります。
ずらさないと、エラーバーがどちらのグループのバーか分かりません。
エラーバーをずらす場合は、geom_errorbar()内で
positionを指定します。
ggplot(cabbage_exp, aes(x=Date,y=Weight,fill=Cultivar)) + geom_bar(position="dodge",stat="identity")+ geom_errorbar(aes(ymin=Weight-se,ymax=Weight+se), position = position_dodge(.9),width=.2)
折れ線グラフ
#複数回利用するため、オブジェクトに格納 pd <- position_dodge(.3) #エラーバー → 折れ線 → マークの順にプロット ggplot(cabbage_exp,aes(x=Date,y=Weight,colour=Cultivar,group=Cultivar))+ geom_errorbar(aes(ymin=Weight-se,ymax=Weight+se), width=.2,size=.25,colour="black",position=pd)+ geom_line(position=pd)+ geom_point(position=pd,size=2.5)
ファセット
各ファセットに注釈を入れていきます。
mpg. ggplot2 2.1.0データセットを使います。
> str(mpg) 'data.frame': 234 obs. of 11 variables: $ manufacturer: Factor w/ 15 levels "audi","chevrolet",..: 1 1 1 1 1 1 1 1 1 1 ... $ model : Factor w/ 38 levels "4runner 4wd",..: 2 2 2 2 2 2 2 3 3 3 ... $ displ : num 1.8 1.8 2 2 2.8 2.8 3.1 1.8 1.8 2 ... $ year : int 1999 1999 2008 2008 1999 1999 2008 1999 1999 2008 ... $ cyl : int 4 4 4 4 6 6 6 4 4 4 ... $ trans : Factor w/ 10 levels "auto(av)","auto(l3)",..: 4 9 10 1 4 9 1 9 4 10 ... $ drv : Factor w/ 3 levels "4","f","r": 2 2 2 2 2 2 2 1 1 1 ... $ cty : int 18 21 20 21 16 18 18 18 16 20 ... $ hwy : int 29 29 31 30 26 26 27 26 25 28 ... $ fl : Factor w/ 5 levels "c","d","e","p",..: 4 4 4 4 4 4 4 4 4 4 ... $ class : Factor w/ 7 levels "2seater","compact",..: 2 2 2 2 2 2 2 2 2 2 ...
この形でマッピングします。
- x軸:displ-ピストンが動ける容積(リットルで表現)
- y軸:hwy-ガロンあたり走れる距離(マイルで表現)(高速で実験)
- ファセット:drv-駆動方式
まずは、上記のマッピングでプロットします。
p <- ggplot(mpg, aes(x=displ,y=hwy)) + geom_point() + facet_grid(. ~ drv) p
各ファセットに注釈を追加するには、
geom_text()と注釈用のデータフレームを使います。
#上のグラフは、drvでファセットにしているので #「drv」という列名と値を合わせる必要があります。 f_labels <- data.frame(drv = c("4","f","r"), label = c("4wd","Front","Rear")) > f_labels drv label 1 4 4wd 2 f Front 3 r Rear p + geom_text(x=6, y=40,aes(label=label),data=f_labels)
ファセットに指定した"drv"列の値と
注釈用データフレームの"drv"列の値が一致させる必要があります。
一致していないとこんなグラフになってしまいます。
#あえて、FFを指定して、一致させないようにしています。 ng_lables <- data.frame(drv=c("4","FF","r"), label = c("4wd","Front","Rear")) p + geom_text(x=6, y=40,aes(label=label),data=ng_lables)
注釈に使うデータフレームですが、ファセットに指定した列以外に、
複数の列を用意して、geom_text()を複数回指定できます。
#この様に、drv列以外に、formula列とr2列を用意します > labels drv formula r2 1 4 italic(y) == 30.68 -2.88 * italic(x) italic(R^2) == 0.65 2 f italic(y) == 37.38 -3.60 * italic(x) italic(R^2) == 0.36 3 r italic(y) == 25.78 -0.92 * italic(x) italic(R^2) == 0.04 #回帰式を引いて p + geom_smooth(method=lm,se=FALSE)+ #formula列の値を数式として追加して geom_text(x=3,y=40,aes(label=formula), data=labels,parse = TRUE,hjust=0) + #r2列の値も数式として追加します geom_text(x=3,y=35,aes(label=r2), data=labels,parse = TRUE,hjust=0)
geom_text()を使って注釈を追加しましたが、
annotate()を使うとどうなるか確認してみます。
#テキスト p + annotate("text",x=6,y=42,label="label text")
#線分 p + annotate("segment",x = 3,xend = 6,y=30,yend=40)
#網掛け p + annotate("rect",xmin = 3,xmax = 6,ymin=30,ymax=40, fill="lightblue",alpha=.3)
annotate()を使うと全ての図に同じ内容が適用されますね。
前回の記事では、geom_text()を使うと、データの数だけプロットされました。
ファセットの場合は、geom_text()とデータフレームの組み合わせが正しいようです。
注釈を入れるのは、この記事で終わりです。
次回の記事からは、軸を制御する方法を扱っていきます。