ggplot2を使って、注釈を入れる-1
R グラフィックス クックブック 20回目
ggplot2パッケージを利用して、図内に注釈を入れます。
注釈
データの解釈をサポートするために、図内に注釈を入れるのですが、
注釈自体は、いろいろあります。
- テキスト(文字列、数式)
- 線(線分、矢印)
- 網掛け
- 強調
- エラーバー
これらを、1個ずつ取り上げます。
最後にファセットグリッドで、グループ化された全ての図に
注釈を入れる方法を取り上げます。
テキスト(文字列、数式)
annotate()を使います。
第1引数に、textを指定します。
まずは、注釈を入れる図を用意します。
データセットはR: Old Faithful Geyser Dataを使います。
p <- ggplot(faithful, aes(x=eruptions, y=waiting)) + geom_point() p
文字列の注釈を入れます。
#注釈を入れる位置を、x軸/y軸の値で指定します。 #文字列は、label引数に指定します。 p + annotate("text", x=3, y=48, label="Group 1") + annotate("text", x=4.5, y=65, label="Group 2")
x軸/y軸が、連続値の場合は、Infを用いて、
図のコーナーに文字列を配置することができます。
コーナーに配置する場合は、hjustやvjustで調整する必要があります。
p + annotate("text",x=-Inf,y=Inf,label="Upper Left",hjust=-.2,vjust=2) + annotate("text",x=mean(range(faithful$eruptions)),y=-Inf,label="Bottom Middle",vjust=-.4)
注釈文字列のフォントや斜体、色やサイズも指定できます。
p + annotate("text", x=3, y=48, label="Group 1", family="serif",fontface="italic",colour="darkred",size=3) + annotate("text", x=4.5, y=65, label="Group 2", family="serif",fontface="italic",colour="blue",size=10)
文字列を注釈に入れる際には、geom_text()は使わない方が良いです。
geom_text()は、データの数だけ、繰り返し実行されてしまいます。
#Group 2の文字列がオーバープロットです。 #透過を0.1に指定していますが、 #透過が分からないくらい重ねてプロットされています。 p + annotate("text", x=3, y=48, label="Group 1", family="serif",fontface="italic",colour="darkred",size=10) + geom_text(x=4.5,y=65,label="Group 2", alpha=.1)
文字列に数式表現を使う場合は、parse引数に、TRUEを指定します。
p <- ggplot(data.frame(x=c(-3,3)),aes(x=x)) + stat_function(fun = dnorm) #parse=TRUEで、labelが数式表現であることを指定します。 p + annotate("text", x=2, y=0.3, parse=TRUE, label="frac(1,sqrt(2 * pi)) * e ^ {-x^2 / 2}")
数式表現内で、プレーンテキストを使う場合は、プレーンテキスト部分を
シングルクォーテーションでくくります。
#Function: 部分がプレーンテキストです。 p + annotate("text", x=2, y=0.3, parse=TRUE, label="'Function: ' * y==frac(1,sqrt(2 * pi)) * e ^ {-x^2 / 2}")
線(線分、矢印)
線により使う関数が異なります。
- 水平線:geom_hline()
- 垂直線:geom_vline()
- 傾きがある線:geom_abline()
このデータセットを使います。
R: Risk Factors Associated with Low Infant Birth Weight
グループ化に用いる列をファクタにして、ラベルを設定します。
birthwt1 <- birthwt birthwt1$smoke <- factor(birthwt1$smoke) birthwt1$smoke <- revalue(birthwt1$smoke, c("0"="No Smoke","1"="Smoke"))
まずは、注釈なしでプロットします。
p <- ggplot(birthwt1, aes(x=age,y=bwt,colour=smoke)) + geom_point() p
水平線と、垂直線を追加します。
#線を引く位置を、水平線ならy軸の値、垂直線ならx軸の値で指定します。 p + geom_hline(yintercept=2000) + geom_vline(xintercept=20)
傾きのある線を追加します。
#y=slope * 100 + interceptの傾きのある線を図示します。 p + geom_abline(intercept=500,slope=100)
別途、算出した値の線を追加することもできます。
グループ化している項目ごとに、平均値を算出します。
library(plyr) bw_means <- ddply(birthwt1,"smoke",summarise,bwt=mean(bwt)) bw_means smoke bwt 1 No Smoke 3055.696 2 Smoke 2771.919
上で算出した、グループ化項目と平均値のデータフレームを
水平線に設定します。
p + geom_hline(aes(yintercept=bwt,colour=smoke),data=bw_means, linetype="dashed",size=1)
軸が離散値の場合は、ファクタのレベルを指定することで
水平線、垂直線を追加できます。
x軸が離散値の図を、サンプルに使います。
pb <- ggplot(birthwt1,aes(x=smoke,y=bwt)) + geom_point() pb
離散値としているsmoke列は、ファクタで、
1つ目のNo Smokeのレベルは1、2つ目のSmokeのレベルは2となっています。
> str(birthwt1$smoke) Factor w/ 2 levels "No Smoke","Smoke": 1 1 2 2 2 1 1 1 2 2 ...
ファクタのレベルを指定することで、線を引くことができます。
#ファクタのレベルを数値で指定します。 pb + geom_vline(xintercept=2)
上は、ファクタのレベルを数値で指定しましたが、
which(levels())を用いることで、名称から指定することもできます。
pb + geom_vline(xintercept = which(levels(birthwt1$smoke)=="No Smoke"))
今までは「線」を扱ってきましたが、ここからは「線分」を追加していきます。
線分は、annotate()を使い、引数に、"segment"を指定します。
この図を使います。
線分を追加するには、x軸の開始値と終了値、y軸の開始値と終了値を指定します。
#x軸は、x~xendで指定します。 #y軸は、y~yendで指定します。 上のグラフ + annotate("segment", x=1950,xend=1980, y=-.25,yend=0.25, colour="blue", size=3)
矢印や、線分の両端をT字にするためには、gridパッケージのallow()を使います。
library(grid) #矢印はarrow() p + annotate("segment",x=1850,xend=1820,y=-.8,yend=-.95,colour="blue", size=2,arrow=arrow())+ #両端がT字にするには、ends引数を指定します。 annotate("segment",x=1950,xend=1980,y=-.25,yend=-.25, arrow=arrow(ends = "both",angle = 90,length = unit(.2,"cm")))
網掛け
annotate()を使います。引数は、rectです。
範囲の指定が、線分とちょっと異なります。
#x軸は、xmin~xmaxで指定します #y軸は、ymin~ymaxで指定します p + annotate("rect",xmin=1950,xmax=1980,ymin=-1,ymax=1, alpha=.1,fill="blue") + annotate("rect",xmin=1800,xmax=2000,ymin=-1,ymax=-.5, alpha=.1,fill="green")
今までの注釈は、端から端までの線を除き、全てannotate()を使っています。
- 文字列:annotate("text",~)
- 線分:annotate("segment",~)
- 網掛け:annotate("rect",~)
注意点は、データの数だけプロットされるgeom_text()を使わないことです。
次回は、強調表示とエラーバー、グリッドで分割された図を扱います。