本稿はRを学び始めたプログラマが学習中に残したメモ書きです。
3回目の今回は、グラフ描画機能を使ってドラ○もんを描こうとして、出来栄えにがっかりした様子が記録されています。
Rのバージョンは2.10.1。
まずは青い丸を描いてみる。手っ取り早い方法として、grid.circleを使うと描けるそうな。
library(grid) grid.circle( x=0.5, y=0.5, r=0.1, gp=gpar(fill="blue") )
gridにはrectやpolygonなどがいるから、たいていの絵は表現できそう。けど、これを使っていたらグラフを描く勉強にならないので本稿では封印します。
円を書くだけなら、普通のplotでこんな感じでも描けるはず。
# 空の領域を用意 plot( x=0:1, y=0:1, type='n' ) # 丸を2つ描いてみる(cexで通常の10倍の大きさを指定) points( c(0.4, 0.6), c(0.5, 0.5), pch=16, col=4, cex=10 )
1項目だけのpie-chartでも円にはなるよね。
pie(c(1), col = "blue", radius=0.3, labels="", border=NA)
circleとか使わなくてもいろいろ描き方はあるようだ。
上みたいな方法で丸は描けるけど、関数でも描いてみたいよね。
plot.new() plot.window(ylim=-c(-5,5), xlim=-c(-5,5)) curve(sqrt(1 - x^2), from=-1, to=1, add=T, col="blue", lwd=10) curve(sqrt(1 - x^2) * -1, from=-1, to=1, add=T, col="blue", lwd=10)
一応円らしくなった。
ところでgnuplotで描く時みたいなcos(t),sin(t)みたいなやり方はどう書けばできるんだろう。
たとえば下記のように書いた場合。
t <- -100:100 plot( sin(t), cos(t), type="l" )
綺麗だけどちょっと違う。数字を増やせば円にならなくはないけど。
2012/05/10追記
こうやればいけるようだ。
t <- seq(-pi, pi, length=100) lines(c(-1, cos(t)), c(0, sin(t)))
ヤツの目は完璧な丸ではなく楕円形をしている。
試しにアルファベットのOを指定位置に描画して目らしきものを作ってみる。
plot(c(0.4, 0.6), c(0.5, 0.5), pch='O', cex=5, xlim=c(0,1), ylim=c(0,1)) par(new=T) plot(c(0.42, 0.58), c(0.48, 0.48), pch='O', cex=1, xlim=c(0,1), ylim=c(0,1))
割とアリ?
でも線の太さの調節ができなさそうなので、円の時と同じくcurveで描いてみる。
plot.new() plot.window(ylim=-c(-5,5), xlim=-c(-5,5)) # 左目(位置をずらしつつ30%ほど縦に伸びてもらう) curve(sqrt(1 - (x+1)^2) * 1.3, from=-2, to=-0, add=T, lwd=10) curve(sqrt(1 - (x+1)^2) * -1.3, from=-2, to=-0, add=T, lwd=10) # 右目 curve(sqrt(1 - (x-1)^2) * 1.3, from=0, to=2, add=T, lwd=10) curve(sqrt(1 - (x-1)^2) * -1.3, from=0, to=2, add=T, lwd=10) # 瞳も入れておこう points( c(0.5, -0.5), c(0.5, 0.5), pch=16, cex=2 )
うん、なんかそれっぽい目になった。
これだと白目を塗りつぶせないので、別途typeをhにした白目を下描して、その上に目を描くことにする。
とりあえず適当なサイズの曲線を描いてみる。
curve(sqrt(2 - x^2) * -1, from=-1.4, to=1.4, xlim=c(-1.5, 1.5), ylim=c(-1.5, 1.5), lwd=3)
ちょっと大きいので高さを半分にしてみる。
curve(sqrt(2 - x^2) / -2, from=-1.4, to=1.4, xlim=c(-1.5, 1.5), ylim=c(-1.5, 1.5), lwd=3)
口っぽい、かな?
鈴はちゃんと描くと面倒なので、cexを3に設定して下記のような模様に出てきてもらうことにする。
points( 0, -1.5, pch=10, cex=3, col="black" )
これの下に黄色い丸を被せると、こうなる。
points( 0, -1.5, pch=16, cex=3, col="yellow" ) points( 0, -1.5, pch=10, cex=3, col="black" )
鈴っぽく見える・・・だろうか。テニスボールになら見える。
とりあえず部品の描き方は頭に入ったので、通しで顔だけ描いてみる。
plot.new() plot.window(ylim=-c(8,-8), xlim=-c(8,-8)) # 顔の青い部分 points( 0, 2, pch=16, col="blue", cex=29 ) # 顔の白い部分 points( 0, 0.9, pch=16, col="white", cex=21 ) # 白目 curve(sqrt(1 - (x+1)^2) * 1.3 + 2.9, from=-1.9, to=-0.2, add=T, lwd=3, type="h", col="white") curve(sqrt(1 - (x-1)^2) * 1.3 + 2.9, from=0.2, to=1.9, add=T, lwd=3, type="h", col="white") # 左目 curve(sqrt(1 - (x+1)^2) * 1.3 + 3, from=-2, to=-0, add=T, lwd=4, type="s") curve(sqrt(1 - (x+1)^2) * -1.3 + 3, from=-2, to=-0, add=T, lwd=4) # 右目 curve(sqrt(1 - (x-1)^2) * 1.3 + 3, from=0, to=2, add=T, lwd=4) curve(sqrt(1 - (x-1)^2) * -1.3 + 3, from=0, to=2, add=T, lwd=4) # 瞳 points( c(0.5, -0.5), c(2.7, 2.7), pch=16, cex=2 ) # 鼻 lines( c(0, 0), c(1.5, -0.5), lwd=3 ) points( 0, 1.7, pch=16, cex=3, col="red" ) points( 0, 1.7, pch=1, cex=3, col="black", lwd=2 ) # ヒゲ lines( c(1, 2.1), c( 0.7, 1.2 ), lwd=3 ) lines( c(1, 2.2), c( 0.6, 0.6 ), lwd=3 ) lines( c(1, 2.1), c( 0.5, 0.0 ), lwd=3 ) lines( c(-1, -2.1), c( 0.7, 1.2 ), lwd=3 ) lines( c(-1, -2.2), c( 0.6, 0.6 ), lwd=3 ) lines( c(-1, -2.1), c( 0.5, 0.0 ), lwd=3 ) # 口 curve(sqrt(2 - x^2) / -2, from=-1.4, to=1.4, add=T, lwd=3) # 首輪 lines( c(-1.8, 1.8), c( -1.15, -1.15 ), lwd=8, col="red" ) curve((x / 2.5)^8 * -1 - 1, from=-1.95, to=1.95, add=T, lwd=3) curve((x / 2.5)^8 - 1.35, from=-1.9, to=1.9, add=T, lwd=3) # 鈴 points( 0, -1.5, pch=16, cex=3, col="yellow" ) points( 0, -1.5, pch=10, cex=3, col="black" )
割とベタベタな描き方だけど、points, lines, curveといった基本的な機能だけでなんとかしています。
さて、上記の命令を実行した結果がこちら。
うーん、なんだろう。似てるんだけどどこか偽物っぽい感じがする。
どこを直せばもっと本物っぽくなるのだろう。
試行錯誤してみたけどなかなか似てくれなかったので、今日はここまで。そもそも絵心の問題でうまくいってない気がする。
とりあえず今回の試みで、Rは極めればお絵描きソフトとしても使えそうなことが分かりました。きっと世の中にはこの手のマニアの人がいて、日夜綺麗な図形や分散を描いて恍惚とした表情を浮かべているのでしょう。
自分もせめてもう少し似たドラ○もんが描けるくらいには、精進したいと思います。