ggplot2を使って、折れ線グラフを作る-1
R グラフィックス クックブック 7回目
ggplot2パッケージを利用して、折れ線グラフを作成していきます。
この3つを対象にします。
- 折れ線グラフ
- 点をもつ折れ線グラフ
- 複数の線の折れ線グラフ
折れ線グラフ
データはこちらを使います。
R: Biochemical Oxygen Demand
> BOD Time demand 1 1 8.3 2 2 10.3 3 3 19.0 4 4 16.0 5 5 15.6 6 7 19.8 > str(BOD) 'data.frame': 6 obs. of 2 variables: $ Time : num 1 2 3 4 5 7 $ demand: num 8.3 10.3 19 16 15.6 19.8 - attr(*, "reference")= chr "A1.4, p. 270"
x軸にTime列を、y軸にdemand列をマッピングし、折れ線グラフで図示します。
ggplot(BOD, aes(x=Time,y=demand)) + geom_line()
Time=6に該当するデータが存在しないのに、図示されています。
Time列が、数値型で連続値と捉えれられているためです。
$ Time : num 1 2 3 4 5 7
離散値にすれば、データセットに含まれないデータは図示されません。
離散値とするためには、ファクタを使います。
#BODデータセットを変更しないように、別オブジェクトに格納する BOD_1 <- BOD #Time列の値をファクタに変換する BOD_1$Time <- factor(BOD_1$Time)
ファクタに変換することで、データ毎にラベルづけが行われます。
$ Time : Factor w/ 6 levels "1","2","3","4",..: 1 2 3 4 5 6
Time列をファクタに変換したBOD_1データセットを、折れ線グラフに図示します。
#group引数でdemandデータが同じグループに属していることを示す ggplot(BOD_1, aes(x=Time,y=demand, group=1)) + geom_line()
折れ線グラフのy軸は、
マッピングされたデータの最小値~最大値を含むように調整されます。
y軸の表示範囲は、0始まりにした方が良い場合もあります。
そのためには、下記の2つがあります。
- ylim()で範囲を指定する
- expand_limits()で任意の値を含む様に指定する
変更点の違いだけを明確にするために、重複部分を変数に取ります。
bodLineChart <- ggplot(BOD_1, aes(x=Time,y=demand, group=1)) + geom_line()
ylim()で範囲を指定する
y軸の表示最小値~表示最大値を指定します。
bodLineChart + ylim(0, max(BOD_1$demand))
expand_limits()で任意の値を含む様に指定する
グラフに表示する値を指定します。
bodLineChart + expand_limits(y=5)
ちなみに、下記の2つのコマンドは同じグラフになります。
expand_limitsの表示最大値は、データの最大値を取ります。
bodLineChart + ylim(0, max(BOD_1$demand)) bodLineChart + expand_limits(y=0)
点をもつ折れ線グラフ
y軸にマッピングされたデータの図示部分に、点を追加します。こんな図です。
(データは、BOD_1データセットを使っています。)
上のグラフのコードはこちらです。(拍子抜け・・・)
ggplot(BOD_1, aes(x=Time,y=demand, group=1)) + geom_line() + geom_point()
geom_point()が追加されただけですね。
この点を追加した折れ線グラフですが、
x軸に対して、データが等間隔に存在しない場合に有効です。
(下記グラフ、大昔は推定値みたいです。そんな頻繁には要らないデータです。)
余談ですが、y軸を対数表示にすると、近代の人口増加が伸びすぎな事が分かります。
複数の線の折れ線グラフ
データはこちらを使います。
R: The Effect of Vitamin C on Tooth Growth in Guinea Pigs
> head(ToothGrowth) len supp dose 1 4.2 VC 0.5 2 11.5 VC 0.5 3 7.3 VC 0.5 4 5.8 VC 0.5 5 6.4 VC 0.5 6 10.0 VC 0.5 > str(ToothGrowth) 'data.frame': 60 obs. of 3 variables: $ len : num 4.2 11.5 7.3 5.8 6.4 10 11.2 11.2 5.2 7 ... $ supp: Factor w/ 2 levels "OJ","VC": 2 2 2 2 2 2 2 2 2 2 ... $ dose: num 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 ...
dose列をx軸にとり、supp列の値でグループ化された、lenの平均値を
折れ線グラフに図示したいと思います。
データの加工にplyrパッケージを利用します。(最近、個人的に大活躍)
CRAN - Package plyr
library(plyr) tg <- ddply(ToothGrowth, c("supp","dose"), summarise, length=mean(len))
加工したデータは、こちらです。
> tg supp dose length 1 OJ 0.5 13.23 2 OJ 1.0 22.70 3 OJ 2.0 26.06 4 VC 0.5 7.98 5 VC 1.0 16.77 6 VC 2.0 26.14 > str(tg) 'data.frame': 6 obs. of 3 variables: $ supp : Factor w/ 2 levels "OJ","VC": 1 1 1 2 2 2 $ dose : num 0.5 1 2 0.5 1 2 $ length: num 13.23 22.7 26.06 7.98 16.77 ...
複数の線を図示するには、colourかlinetypeに離散値のグループを指定します。
- colourに指定した場合
ggplot(tg, aes(x=dose,y=length,colour=supp)) + geom_line()
supp値が色で分かれて図示されています。
- linetypeに指定した場合
ggplot(tg, aes(x=dose,y=length,linetype=supp)) + geom_line()
supp値が線の種類で(実線と破線)分かれて図示されています。
この記事の最初のグラフでも触れた様に、dose列が数値型であり、
連続値として扱われているため、データに存在しない1.5がグラフに表れています。
そのため、ファクタに変換し、離散値として扱います。
ggplot(tg, aes(x=factor(dose),y=length,colour=supp, group=supp)) + geom_line()
(x軸で、1.5の列が消えました。)
わざわざsupp列で集約したのに、groupを指定しないとどうなるのか?
#groupを指定しないで、図示してみる ggplot(tg,aes(x=dose,y=length)) + geom_line()
こんなギザギザのグラフになります。
それぞれのdose値で、2点のデータが図示されています。
groupが指定されないと、どの値でグループ化するのか分からないためです。
ギザギザが出てきたら、何かしら漏れている感じでしょうね。
複数の折れ線グラフにも、点を表示することができます。
ggplot(tg, aes(x=dose,y=length,shape=supp)) + geom_line() + geom_point(size=4)
ggplot(tg, aes(x=dose,y=length,fill=supp)) + geom_line() + geom_point(size=4,shape=23)
複数の折れ線グラフに点を表示する時は、groupの指定の代わりに、
shapeやfillを指定します。後は、勝手にグループ化してくれます。
上のグラフは、x軸=2.0で、OJグループとVCグループの値が重なっています。
(データがそうなのだからしょうがないと思うけど・・・)
過去記事でも散々触れてきた、position_dodgeでずらすことができます。
(データがそうなのだから、ずらす必要はないと思うんだけど・・・)
こんな感じです。
ggplot(tg, aes(x=dose,y=length,shape=supp)) + geom_line(position = position_dodge(0.2)) + geom_point(position = position_dodge(0.2), size=4)
次回は、線や点の体裁を変更したり、網掛け領域付きにしてみます。