概要

本稿はRを学び始めたプログラマが学習中に残したメモ書きです。

3回目の今回は、グラフ描画機能を使ってドラ○もんを描こうとして、出来栄えにがっかりした様子が記録されています。

Rのバージョンは2.10.1。

@CretedDate 2012/05/08
@Env R2.10.1, Ubuntu10.04

丸を描いてみる

まずは青い丸を描いてみる。手っ取り早い方法として、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 )

青い丸2つ

1項目だけのpie-chartでも円にはなるよね。

pie(c(1), col = "blue", radius=0.3, labels="", border=NA)

pichartで円

circleとか使わなくてもいろいろ描き方はあるようだ。

curveで丸を描いてみる

上みたいな方法で丸は描けるけど、関数でも描いてみたいよね。

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)

curveで円

一応円らしくなった。

ところで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))

Oの描画

割とアリ?

でも線の太さの調節ができなさそうなので、円の時と同じく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 )

curveを使った瞳

うん、なんかそれっぽい目になった。

これだと白目を塗りつぶせないので、別途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は極めればお絵描きソフトとしても使えそうなことが分かりました。きっと世の中にはこの手のマニアの人がいて、日夜綺麗な図形や分散を描いて恍惚とした表情を浮かべているのでしょう。

自分もせめてもう少し似たドラ○もんが描けるくらいには、精進したいと思います。