2009年声優言及数 作業メモ(7) データの解析 つづき

解析が終わったので、グラフを書くことに。せっかくなので、今年は噂のggplot2を使ってみようかと。こちらのサイトなどを参考にしつつ、公式のリファレンスに載ってるサンプルを片っ端から試していけば何となく使い方は理解できました。

使う前は「何だこりゃ、よくわかんねー」って思ったけど、慣れてくると楽しいですね。plotの暗号みたいな書式よりもコードが見やすいのも嬉しい限り。
で、最終的にこんな感じに。

## read readpng2r output, and return data frame
## input:
## key	name	200801	200802	...
## output:
## name(rowname) Jan 2008 Feb 2008 ...
read.sy.file <- function(filename, pickup=1:12){
    # read file
    l <- read.delim(filename)
    # 2nd row contains name
    rownames(l) <- l[,2]
    # delete escaped-name and name
    l <- l[,-c(1,2)]
    # transform "X200801" -> "2008 Jan"
    n <- colnames(l)
    colnames(l) <- paste(month.abb[as.integer(substr(n,6,7))], substr(n,2,5))
    # pickup data
    l[,pickup]
}

## calc linear regression parameter from given data
## input : data frame
## 
##  Jan 2009 Feb 2009
## ------------------
##     2.500    0.000
##  1397.416 1354.633
##     0.000    2.010
## ..
## ..
stat.sy <- function(df.sy, pickup=1:12){
    # calc lm for each row
    lm.ba <- apply(df.sy, 1, function(v) coef(lm(y~x, data.frame(y=as.numeric(v), x=pickup))))
    a     <- lm.ba[2,]
    b     <- lm.ba[1,]
    # calc last/first rate using regression parameter
    first.data <- pickup[1] * a + b
    last.data  <- pickup[length(pickup)] * a + b
    shift      <- min(first.data) - 1  ## minimun denominator must be 1
    # create a new data frame
    data.frame(sum=apply(df.sy,1,sum),
               a=a, b=b,
               key=(last.data - shift)/(first.data - shift)
               );
}

## main
library(ggplot2)
library(cairoDevice)

filename <- "readpng2r.2008_2009.out"
pickup   <- 7:24

## read input file
l <- read.sy.file(filename, pickup)
## calc statistics
d <- stat.sy(l, pickup)
## basename (URI-escaped name)
basename <- as.character(read.delim(filename)$key)

## "Jul 2008" -> Date object (used for x-scale of ggplot2)
t     <- Sys.getlocale("LC_TIME")
Sys.setlocale("LC_TIME", "C")
month <- as.Date(strptime(sprintf("%s 01", colnames(l)), "%b %Y %d"))
Sys.setlocale("LC_TIME", t)

## plot
for(i in seq(length(basename))){    
    Cairo_png(sprintf("stat_png/%s.png", basename[i]), pointsize=8, width=4.5, height=3)
    q <- qplot(month, as.numeric(l[i,]), geom=c("point", "path"), colour="#1E5692", xlab="", ylab="")
    q <- q + stat_smooth(fill="#2578C5", alpha=0.1, colour=0)
    q <- q + stat_smooth(method="lm", colour="#DA2025", se=F)
    q <- q + theme_bw()
    q <- q + scale_colour_identity()
    print(q)
    dev.off()
}

はてなダイアリーに貼るので最終的にはpngで出力させたい。ということを考えると、PNGフォーマットで出力できて、アンチエイリアスができて、アルファブレンドに対応しているやり方は・・・色々試してみたのですが、どうやらこの方法しかないみたい。普通にpdfにしてからImagemagickで変換しようとすると、なぜかアンチエイリアスが消えちゃうんだよね。多分、アンチエイリアス+アルファブレンドが両立できてないんだと思われます。

じゃあsmoothのseを消せばいいんだけどさー。そうするともうggplotだか何だか分からなくなっちゃうしな・・・。書きながら、段々普通のplotで事足りたんじゃないかって気がしてきた。

まあ、色々と試行錯誤をしつつ、こんな感じのグラフが出るようになりました。あとは声オタに戻ってコメント書くぞー。

あーつかれた。

追記

今後の改善点。軸のラベル文字が切れてしまうことがあるので、文字をもう少し小さくした方がいいかも。しかしグラフは超キレイ。苦労したけど、使ってよかった。

追記2

Perl、C、Rがそれぞれの得意分野を生かして連携するこの企画、結構嫌いじゃないな。