特徴
以下のようなサンプルデータを用いる。
| month | temperature | precipitation |
|---|---|---|
| 1 | -0.4 | 35.9 |
| 2 | 0.2 | 43.5 |
| 3 | 3.9 | 79.6 |
| 4 | 10.6 | 75.3 |
| 5 | 16.0 | 100.0 |
| 6 | 19.9 | 125.7 |
| 7 | 23.6 | 138.4 |
| 8 | 24.7 | 92.1 |
| 9 | 20.0 | 155.6 |
| 10 | 13.2 | 101.9 |
| 11 | 7.4 | 54.9 |
| 12 | 2.3 | 28.1 |
ここからサンプルデータをダウンロードできるはず。
もしくはExcelなどを開き、上記の様に入力し、CSV形式で保存する。
csvファイルの読み込みはread.csv()で行う。
smp <- read.csv("./data/sample.csv")
気温と降水量を変数に格納する。気温は英語でtemperatureなので、変数名はtemp、降水はprecipitationなので、変数名はpptにした。地点名は今回はsampleなので、後ろに_smpとつける。
temp_smp <- smp$Temperature
ppt_smp <- smp$Precipitation
Waltarの気候図では右側の縦軸の降水量は気温の2倍の値が対応することである。また、月降水量が100mmを超えると縮尺が10分の1になる。今回のグラフでは、気温をそのままに、降水量を変換させることで描画する。
ppt_smp[ppt_smp<=100] <- ppt_smp[ppt_smp<=100]/2
ppt_smp[ppt_smp>100] <- ppt_smp[ppt_smp>100] * 0.1 + 40
1行目では、月降水量が100mm以下の場合は縮尺を2分の1にしている。
2行目では、月降水量が100mmを超える場合に縮尺を10分の1にしている。なお、この処理は値を-100してから、10分の1にして、+50しても同じである。原理的にはその方が正しいが、簡単な実装のため、このようなコードになっている。
次に、後で使う月の変数を作成する。変数monthには英語の月の名前の頭文字を、変数mには1~12までの数字を入れている。c()はベクトルを作成する関数(cはcombineの略)で、1:12では1~12まで1刻みのベクトルを作成している。
month <- c("J", "F", "M", "A", "M", "J", "J", "A", "S", "O", "N", "D")
m <- 1:12
まずはグラフィックパラメータを調節する。
par(mar=c(5,5,5,5), mgp=c(2.5, 0.5, 0))
気温を赤色の折れ線グラフで描画する。
plot(m, temp_smp, type="l", lwd=2.4, xaxs="i", yaxs="i", ann=FALSE, axes=FALSE, col="#FA4141", ylim=c(-5, 60))

降水量を青色の折れ線グラフで描画する。
lines(m, ppt_smp, lwd=2.4, col="#0E67F5")

降水量が気温の2倍を上回る月は影をつける。
polygon(c(m,rev(m)), c(ppt_smp, rev(temp_smp+0.2)), density=10, angle=90, col="#0E67F5", border=NA)

降水量が気温の2倍を下回る月があるときは上からもう一度気温のグラフを描画する。今回はいらないが一応コードを書く。
par(new=T)
plot(m, temp_smp, type="l", lwd=2.4, xaxs="i", yaxs="i", ann=FALSE, axes=FALSE, col="#FA4141", ylim=c(-5, 60))
降水量が月100mmを上回る月は塗りつぶす。
wet_smp <- ifelse(ppt_smp > 50, ppt_smp, 50)
polygon(x=c(m, rev(m)), y=c(wet_smp, rep(50, times=12)), col="#0E67F5", border=NA)

はみ出る分を白く塗りつぶす
polygon(x=c(m[1:12], rev(m[1:12])), y=c(ppt_smp[1:12]+0.2, rep(60, times=12)), col="white", border=NA)

最初はx軸を描く
abline(h=0, lwd=1.1)

月の名前を入れ、区切りがわかりやすいように、月ごとに点線を入れる。
axis(1, las=1,tck=1, lty="dotted", at=m, labels=month, line=0)

気温軸を左の縦軸に追加する。
axis(2, las=2, tck=-0.02, at=c(-50, -40, -30, -20, -10, 0, 10, 20, 30, 40, 50, 60, 70), labels=c(-50, -40, -30, -20, -10, 0, 10, 20, 30, 40, NA, NA, NA), col.axis="#FA4141")
mtext("°C", side=2, at=70, line=0.5, las=1, col="#FA4141")

降水量の軸を右側の縦軸に追加する。
axis(4, las=2, tck=-0.02, at=c(-50, -40, -30, -20, -10, 0, 10, 20, 30, 40, 50, 60, 70), labels=c(NA, NA, NA, NA, NA, 0, 20, 40, 60, 80, 100, 200, 300), col.axis="#0E67F5")
mtext("mm", side=4, at=70, line=0.5, las=1, col="#0E67F5")

値がわかりやすいように、横に点線を入れる。
abline(h=c(seq(10,70, by=10)), lty="dotted")
abline(h=c(seq(-40,-10, by=10)), lty="dotted")

タイトルを付ける。上から順番に地点名/国名、座標、標高である。
mtext("Location/Country", side=3, line=3.4, cex=1.2)
mtext(paste("36°14'16.8\"N/137°58'19.1\"E"), side=3, line=2.2, cex=1.2)
mtext(paste("592m"), side=3, line=1, cex=1.2)

下に年平均気温と年間降水量を追加する。

以上で完成である。お好みで色や線幅、軸などを調整する。
最後に、今回のコード全文を貼る。
# データファイルの読み込み
smp <- read.csv("./data/sample.csv")
temp_smp <- smp$Temperature # 気温
ppt_smp <- smp$Precipitation # 降水量
# 降水量は気温軸のスケールの2分の1に対応する(月100mm以下の場合)
ppt_smp[ppt_smp<=100] <- ppt_smp[ppt_smp<=100]/2
# 降水量が100mmを超える月はスケールを10分の1に圧縮する
ppt_smp[ppt_smp>100] <- ppt_smp[ppt_smp>100] * 0.1 + 40
# もしくは、100mmを超える分は-100してから10分の1にして、50を足しても同じ。原理としてはこちらが正しいが、処理が複雑
# 横軸は月
#month <- c("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec")
month <- c("J", "F", "M", "A", "M", "J", "J", "A", "S", "O", "N", "D")
m <- 1:12
# プロット
# 描画領域を少し調整する
par(mar=c(5,5,5,5), mgp=c(2.5, 0.5, 0))
# 気温を折れ線グラフで描画(赤色)
plot(m, temp_smp, type="l", lwd=2.4, xaxs="i", yaxs="i", ann=FALSE, axes=FALSE, col="#FA4141", ylim=c(-5, 60))
# 降水量を折れ線グラフで描画(青色)
lines(m, ppt_smp, lwd=2.4, col="#0E67F5")
# 降水量が気温の2倍を上回る月は影をつける
polygon(c(m,rev(m)), c(ppt_smp, rev(temp_smp+0.2)), density=10, angle=90, col="#0E67F5", border=NA)
wet_smp <- ifelse(ppt_smp > 50, ppt_smp, 50)
# 降水量が100mmを上回る月は塗りつぶす
polygon(x=c(m, rev(m)), y=c(wet_smp, rep(50, times=12)), col="#0E67F5", border=NA)
# はみ出る分を消す(実際には白く塗りつぶしている)
polygon(x=c(m[1:12], rev(m[1:12])), y=c(ppt_smp[1:12]+0.2, rep(60, times=12)), col="white", border=NA)
# 軸を描いていく
# x軸
abline(h=0, lwd=1.1)
# それぞれの月に点線を引く
axis(1, las=1,tck=1, lty="dotted", at=m, labels=month, line=0)
# 気温の縦軸(左側)
axis(2, las=2, tck=-0.02, at=c(-50, -40, -30, -20, -10, 0, 10, 20, 30, 40, 50, 60, 70), labels=c(-50, -40, -30, -20, -10, 0, 10, 20, 30, 40, NA, NA, NA), col.axis="#FA4141")
mtext("°C", side=2, at=70, line=0.5, las=1, col="#FA4141")
# 降水量の縦軸(右側)
axis(4, las=2, tck=-0.02, at=c(-50, -40, -30, -20, -10, 0, 10, 20, 30, 40, 50, 60, 70), labels=c(NA, NA, NA, NA, NA, 0, 20, 40, 60, 80, 100, 200, 300), col.axis="#0E67F5")
# 降水量の単位
mtext("mm", side=4, at=70, line=0.5, las=1, col="#0E67F5")
# 縦軸に点線で目盛をつける
abline(h=c(seq(10,70, by=10)), lty="dotted")
abline(h=c(seq(-40,-10, by=10)), lty="dotted")
# タイトルをつける
# Station/Location
mtext("Location/Country", side=3, line=3.4, cex=1.2)
# Coordinate
mtext(paste("36°14'16.8\"N/137°58'19.1\"E"), side=3, line=2.2, cex=1.2)
# elevation
mtext(paste("592m"), side=3, line=1, cex=1.2)
# 年平均気温
mtext(paste("Mean temp: ", round(mean(temp_smp), 1), " °C", sep=""), side=1, line=2, cex=1.2, adj=1)
# 年間降水量
mtext(paste("Total Precip: ", round(sum(smp$Precipitation), 0), " mm", sep=""), side=1,line=3, cex=1.2, adj=1)