The One with ...

授業・研究用のメモなどを公開しています

ggplot2: 複数の関数をplotして比較する

関数のパラメータを変えながら,そのplotを比較したい,という場面に日々遭遇します. Mathematicaをつかえば簡単で,例えば

Plot[{
  PDF[NormalDistribution[0, 1], x],
  PDF[NormalDistribution[1, 1], x],
  PDF[NormalDistribution[2, 1], x]}, {x, -6, 6}]

でOKです.

f:id:hamada7418:20190418122206p:plain

凡例が欲しければ,Plot関数のオプションに

PlotLegends -> "Expressions"

と指定します.

f:id:hamada7418:20190418122513p:plain

え?これだけ?というくらい簡単です. 私が普段Mathematicaを愛用している理由が分かっていただけたかと思います.

ところが,こんなに手軽で素晴らしく高機能なMathematicaですが,つかっているユーザが少ないという 難点があります. データとの連携を考え,RPythonをメインに使っている方も多いでしょう.

かくいう私もStanをつかう場合にはRから呼び出しています.

そこでワークフローの効率化のためRStudioで上記の関数比較を実行する方法を,ここにメモしておきます.

R上での関数のplot

もっとも簡単なコードとして

curve(dnorm(x),-4,4)

を試してみます.

f:id:hamada7418:20190418125100p:plain

ファイルとして出力するには

png("hoge/pics.png")
curve(dnorm(x),-4,4)
dev.off()

です.hogeディレクトリにpics.pngが保存されます *1

複数の関数を1つの図に重ねてplotしましょう.par(new=TRUE)でplotを上に重ねて書きます.

curve(dnorm(x),-4,4)
par(new=TRUE)
curve(dnorm(x,1,1),-4,4)

f:id:hamada7418:20190418131007p:plain

グラフを較べる目的ならこれで十分でしょう. 縦軸ラベルの重なりが気になる場合は片方のラベルを消します.

curve(dnorm(x),-4,4)
par(new=TRUE)
curve(dnorm(x,1,1),-4,4,ylab="")

f:id:hamada7418:20190418142109p:plain

線種を変えて,凡例もつけましょう.

curve(dnorm(x),-4,4,lty=1)
par(new=TRUE)
curve(dnorm(x,1,1),-4,4,lty=2,ylab="")
legend("topright",legend=c("mean=0","mean=1"),lty=c(1,2))

f:id:hamada7418:20190418142448p:plain

見やすくなりました.

ggplot2をつかう

ggplot2を使って,グラフの見た目を調整します.

library("ggplot2")
x <- seq(-4,5,0.1)
m0 <- dnorm(x,0,1)
m1 <- dnorm(x,1,1)
data <- data.frame(x=x,y1=m0,y2=m1)
ggplot(data,aes(x))+
    geom_line(aes(y=y1))+ 
    geom_line(aes(y=y2),linetype="dashed")

f:id:hamada7418:20190418165519p:plain

基本的な方針は以下のとおりです.

  1. 独立変数のベクトルxをつくる
  2. dnorm(x,0,1)の出力をベクトルm0に代入
  3. dnorm(x,1,1)の出力をベクトルm1
  4. 上記のベクトルをdata.frameにまとめる
  5. geom_line( )をで曲線をplotする

以上です.ラベルが不要であれば +theme(axis.title=element_blank( ) ) で消去します.このときxlab=" "等を使うと余分な空白が入るので,axis.title=element_blank( ) )を使うとよいでしょう. 背景のグレーが不要ならtheme_bw( )を使って,背景を白黒印刷用に白くします. 以上をまとめためのが,次のコードです

ggplot(data,aes(x))+
    geom_line(aes(y=y1))+ 
    geom_line(aes(y=y2),linetype="dashed")+
    theme_bw() +theme(axis.title=element_blank(),text=element_text(size=9)) 

f:id:hamada7418:20190418165530p:plain

以上です.もっと簡単な方法が分かれば,メモを更新します.

*1:作画デバイス上のエラーが原因で,作成した画像ファイルを開けないことがあります. その場合はdev.offやgraphics.offで作画デバイスを消します