時系列データのプロット

なんか色々書こうかと思ったけど眠くなってきたのでソースだけ。読めばわかると思う。似たようなの昔も書いたけど多少読みやすいと思う。眠いので自分で勝手に思ってるだけかもしれない。
一応温度みたいなデータのプロットを目的としている。
とりあえず先に出力を。


んでソース。コメントが長いだけでそんな複雑なことしてないと思う。たぶん。本当はggplot2でのやり方くらいまで調べたかったが眠いのでとりあえずパス。

## ---- make a test data ----
## 30分間隔で3日間のデータ
Time <- seq(as.POSIXct("2011-08-09 00:00:00"), as.POSIXct("2011-08-11 23:30:00"), length.out = 48*3)
## 一日を周期とする(温度を想定)
tmp <- seq(0, 6*pi, length.out = 48*3)
upper <- sin(tmp)*3 + 30
lower <- sin(tmp)*5 + 20
## こんなかんじ
head(data.frame(Time, upper, lower))


## ---- 普通にプロット ----
plot(Time, upper,
     ylim = c(10, 40),
     xlab = "", ylab = "気温(℃)",
     xaxt = "n",       # x軸を書かない(後で書く)
     type = "l",
     col = "red" )
lines(Time, lower,
      type = "l",
      col = "blue")

## 時刻はまず範囲をrangeで求める。
## 切りの良い単位(daysなど)で丸めておくと見栄えが良い。
## 第2引数(units)に指定できるのは"secs", "mins", "hours", "days"
r <- as.POSIXct(round(range(Time), "days"))
## Axisでx軸描画
## sex.POSIXltでbyに指定できるのは
## sec, min, hour, day DSTday, week, month, year
## 整数とスペースを頭につけると単位を整数倍したものを指定可能
## hoursなどとsを付けてもいいし付けなくても別に怒られない
## DSTは夏時間(daylight savings time)関係の何からしい
## formatには表示形式を指定する。
## 例えば"2011-08-09 23:54:01"のような表示は"%Y-%m-%d %H:%M:%S"
## "05日"を"5日"にするには%e等細かい指定ができる。
## 詳細はstrptimeのヘルプ参照
Axis(at = seq(r[1], r[2], by="12 hours"),
     side = 1, format="%e日%k時")
## グリッドを細かく指定したい場合はgrid()ではなくabline()を
abline(h = seq(10, 40, by=5),
       v = seq(r[1], r[2], by = "6 hours"),
       col = "lightgray", lty = "dotted")


## ---- 差を下に面グラフで表示 ----
## -- 上半分の描画
## 描画位置を上に
par(fig = c(0.5, 10, 5, 10)/10,
    mar = c(0, 4, 4, 4))
## x軸を描かずにプロット
plot(Time, upper,
     ylim = c(10, 40),
     xlab = "", ylab = "気温(℃)",
     xaxt = "n",
     type = "l",
     col = "red",
     ytics = c(10)
     )
lines(Time, lower,
      type = "l",
      col = "blue")
abline(h = seq(10, 40, by=5),
       v = seq(r[1], r[2], by = "6 hours"),
       col = "lightgray", lty = "dotted")
## -- 下半分の描画
## 位置をずらして上書き
par(new=T)
par(fig = c(0.5, 10, 0, 5)/10,
    mar = c(4, 4, 0, 4))
plot(Time, lower-upper,
     ylim = c(-20, 0),
     xlab = "", ylab = "",
     xaxt = "n",       # x軸もy軸も後で書く
     yaxt = "n",
     yaxs = "i",       # y軸方向の端を枠にぴったりくっつける
     type = "n")
## グリッド
abline(h = seq(-20, 0, by = 5),
       v = seq(r[1], r[2], by = "6 hours"),
       col = "lightgray", lty = "dotted")
## polygonで塗りつぶす
xvals <- Time
yvals <- lower-upper
## xvalsとrep(0, length(yvals))のペアで右まで線を引いて、
## rev(xvals)とrev(yvals)のペアで左まで山を描きながら戻る感じ
polygon(c(xvals, rev(xvals)),
        c(rep(0, length(yvals)), rev(yvals)),
        col = rgb(0.5,0.6,1.0, 0.5))
## x軸
Axis(at = seq(r[1], r[2], by="12 hours"),
     side = 1, format="%e日%k時")
Axis(at = seq(-20, 0, by=5), side = 4)
mtext("温度差", side = 4, line = 2)