もうちょっと高度なグラフィックス特集

Rのグラフィックス特集

注意

  • グラフィックスは結果が視覚的なので面白い
  • 夢中になって目的とかを忘れないでね
  • オプションやまほどあるけど、覚える必要はない
    • 「こういうのがあるんだー」ってくらいでいい
    • ログに残しておくと後で楽をできる

内容

  • グラフィックスのいろいろ
  • Rのちょっと細かいけど、知ってると楽にできること
  • ちょっとプログラムを書いて、楽にシミュレーションをやったり。

作図関数について

  • 大別して3種類くらい
    • 高水準作図関数
    • 低水準作図関数
    • 対話的作図関数

高水準作図関数

  • 一枚の完成された図を作成するためのもの
    • 散布図
    • ヒストグラム
  • 多少設定できるけど、とりあえずplotとかhistってやってればできる
  • 楽チン

example

plot(iris)


低水準関数

  • グラフの塗りつぶしとか自分でいろいろ設定するもの
  • 面倒だけど、きちんとしたものを作りたいときには必須

対話的作図関数

  • マウスとかを使ってごにょごにょするやつ
  • 異常値の発見とかに役にたつ
array1 <- 1:7
array2 <- 7:1
array3 <- c("syou6162","y_benjo","wakuteka","twittoru","witchmakers","mickey24","InoHiro")
plot(array1,array2)
identify(array1,array2,array3)


保存とか

  • コピペとかでもできるけど
  • 画像ファイルとして保存するやり方
  • pngで指定
    • dev.offで出力終了
    • プロットはされないよ
  • pdfとかでもおk
png("~/Desktop/syou6162.png")
plot(array1,array2)
dev.off()

便利な時

  • 一枚とか書くときにはそれほど変わらないかもしれない
  • シミュレーションで画像ファイルが30枚とか必要だったとき
  • さっきのコマンドをforで回したりすると幸せになれます

高水準作図関数

  • この辺にいる人たちはもう結構知っている…はず
  • 簡単だけど、あんまり知らない関数とかを紹介していくよ

関数のグラフ

正規分布を出力したりとか

curve(dnorm,-3,3)

X^2分布とか

curve(dchisq(x,3),0,15)

関数名と定義域を指定

  • どんな関数があるの?
  • この辺参照

http://www.okada.jp.org/RWiki/?R%A4%CB%A4%AA%A4%B1%A4%EB%B3%CE%CE%A8%CA%AC%C9%DB

自分で定義した関数もおk

plot(function(x){2*x^3+x^2},-30,30)


棒グラフ

  • ありがち
barplot(1:10)
barplot(1:10,horiz=T,names=letters[1:10],las=1)

オプション

horiz 棒グラフを横にする
names 軸に名前を付ける
las 軸の文字を横で出す

できあがり


進化

  • こんなのも書けるよ


3次元プロット

  • persp関数
    • ごめん、あんまりよくな(ry
  • thetaとかは角度を変える
x <- seq(-10,10,length=50)
y <- x
z <- outer(x,y,function(x,y){r <- sqrt(x^2+y^2);10**sin(r)/r})
persp(x,y,z)
persp(x,y,z,theta=30,phi=30,expand=0.5,col=rainbow(50))

できあがり

outer関数

  • 第一引数と第二引数を関数に適用したものの全ての組み合わせ
    • for文は書かない
> outer(1:9,1:9,"*")
      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
 [1,]    1    2    3    4    5    6    7    8    9
 [2,]    2    4    6    8   10   12   14   16   18
 [3,]    3    6    9   12   15   18   21   24   27
 [4,]    4    8   12   16   20   24   28   32   36
 [5,]    5   10   15   20   25   30   35   40   45
 [6,]    6   12   18   24   30   36   42   48   54
 [7,]    7   14   21   28   35   42   49   56   63
 [8,]    8   16   24   32   40   48   56   64   72
 [9,]    9   18   27   36   45   54   63   72   81

低水準作図

  • 簡単なところからいきましょう
  • タイトル、サブタイトル
plot(rnorm(50),rnorm(50),xlab="あああ",ylab="いいい")
title(main="正規乱数同士の散布図",sub="書いてみたよー")

凡例

  • legend関数
legend(x,y,legend) x,yは位置。legendは名前
lwd 線や点の太さ
lty 線の種類
plot(1:10,1:10,type="l",lty=1)
lines(((1:10)^2)/10,lty=2)
legend(1,5,c("直線","二乗"),lwd=1,lty=c(1,2))

画面の分割

  • mfrowにベクトルを与えてあげる
  • 左上、右上、左下、右下の順
par(mfrow=c(2,2))
plot(sin)
plot(cos)
plot(tan)
plot(dnorm)

できあがり

タイトルを枠の外に書く

  • mtextで外にタイトルを
  • lineはタイトルの位置とか(だと思う)
  • outerは外に書くことを許すよってやつ
  • sideは上に書くよっていっている
    • 回る順番
par(mfrow=c(2,2))
plot(sin)
plot(cos)
plot(tan)
plot(dnorm)
mtext(side=3,line=1,outer=T,text="Title")

失敗…

余白が必要

  • omaで余白の設定が必要
par(oma=c(0,0,4,0))
par(mfrow=c(2,2))
plot(sin)
plot(cos)
plot(tan)
plot(dnorm)
mtext(side=3,line=-3,outer=T,text="Title",cex=3)

できあがり

自由に画面分割

  • cの順番に描画される
mat <- matrix(c(1,3,2,2),2,2,byrow=TRUE)
mat
layout(mat)
plot(sin)
plot(cos)
plot(tan)

できあがり

自由に画面分割2

  • もっと自由にすることもできるよ
par(oma=c(0,0,4,0))
mat <- matrix(c(1,1,1,2,3,4),2,3,byrow=TRUE)
mat
layout(mat)
plot(sin)
plot(cos)
plot(tan)
plot(dnorm)
mtext(side=3,outer=TRUE,text="いろんな関数を描画してみる")

できあがり

Rでグラフィックスを書く意味

  • ただただ書きたいならexcelとかのほうがいい人もいるかもしれない
  • 繰り返し処理で楽をしたいというためってのが結構ある

繰り返し処理のための準備

  • for文
  • pythonっぽい?
for(i in 1:10){
  print(i)
}

paste関数

  • 文字列を結合させるための関数
a <- "Misho"
b <-"キラッ"
paste(a,b,sep="☆")

deparse関数とsubstitute関数

  • グラフィックス関係とかでよく出てくる関数
    • ex.plot
  • こいつらはセットとかでよく使われている
  • substitute関数は引数に使われている変数の中身、ではなくて変数の名前自身とかを返す
    • パラメータの値ではなく、名前が欲しい時に使う
x <- "syou6162"
substitute(x)

deparse関数

  • 普通はdeparse関数をかぶせて使ってあげる
deparse(substitute(x))

同じじゃね?

  • 何でこんなことする必要があるかっていうと返ってくる型が違うから
  • name型っていうのはよく知らない
  • だけど、欲しいのは大抵characterなので、deparseしとく
mode(substitute(x))
mode(deparse(substitute(x)))

最適化の授業

  • 最急降下法というのを習った
    • 微分とか計算してちょこちょこ点を動かしていって、最小にする点を見つけたりする
    • f(x,y)=100(x-y)^2 + (x-1)^2とかいう関数を最小にする
  • 段々よくなっていく様子を見ていきたい!!

こんなの


うまくいかないときもある

  • 自分で与えないといけないパラメータとかがある
    • どんなパラメータのときにうまくいっていないのかとかを見たい
  • 「epsilon」と「tau」を調整する

うまくいかなかった例

epsilon <- 0.1
tau <- 0.1
steepest_descent(epsilon,tau)


どれがうまくいったとかいちいち覚えてられない!!

  • 一度にplotさせよう
    • パラメータの値も一緒に載せよう
par(oma=c(0,0,4,0))
mat <- matrix(1:9,3,3,byrow=TRUE)
mat
layout(mat)
for(epsilon in c(0.1,0.5,0.9)){
  for(tau in c(0.1,0.5,0.9)){
    steepest_descent(epsilon,tau)
  }
}
mtext(side=3,outer=TRUE,text="最急降下法のシミュレーション")

肝心のplotのコードの中身

  • 順を追って説明していくなどする
steepest_descent <- function(epsilon,tau,x_bar1=-10,x_bar2=-20,beta=1,n=2000){
  #関数内関数の定義
  f <- function(x){x1 <- x[1];x2 <- x[2];return(100*(x1-x2)^2+(x1-1)^2)}
 
  #数式微分
  trig.exp <- expression(100*(x1-x2)^2+(x1-1)^2)
  D.sc1 <- D(trig.exp, "x1")
  D.sc2 <- D(trig.exp, "x2")
 
  #最急降下法の計算
  x_vec <- matrix(0,n+1,2,byrow=TRUE)
  for(i in seq(n)){
    nabla_f <- c((function(x1,x2){eval(D.sc1)})(x_bar1,x_bar2),
                 (function(x1,x2){eval(D.sc2)})(x_bar1,x_bar2))
    while(f(c(x_bar1,x_bar2) - beta * nabla_f) >
          f(c(x_bar1,x_bar2)) - epsilon * beta * sum(c((function(x1,x2){eval(D.sc1)})(x_bar1,x_bar2),(function(x1,x2){eval(D.sc2)})(x_bar1,x_bar2))^2)){
      beta <- tau * beta
    }
    a <- beta
    x_bar1_old <- x_bar1
    x_bar1 <- x_bar1 - a * (function(x1,x2){eval(D.sc1)})(x_bar1,x_bar2)
    x_bar2 <- x_bar2 - a * (function(x1,x2){eval(D.sc2)})(x_bar1_old,x_bar2)
    x_vec[i,] <- c(x_bar1,x_bar2)
   }
 
  #3次元のplot関係
  x <- seq(-1,1,length=50)
  y <- x
  z <- outer(x,y,function(x,y){mapply(function(x,y){f(c(x,y))},x,y)})
 
  persp(x,y,z,theta=150,phi=10,expand=0.5) -> res
  x <- x_vec[,1]
  y <- x_vec[,2]
  z <- mapply(function(x,y){f(c(x,y))},x,y)
  title(sub=paste(
          deparse(substitute(tau)),"=",tau,
          " ",
          deparse(substitute(epsilon)),"=",epsilon,
          sep=""))
  lines(trans3d(x,y,z, pmat = res),col="red",lwd=5)
 
  #結果を明示的な形で返さないようにする
  return(invisible(x_vec))
}

もちろん

  • 一度にplotさせるのではなくて、一枚一枚pngに吐き出させるとかでもよい
    • ファイル名とかにパラメータ名と値とかを入れておくとよい

まとめ