R で自動作図
どんな絵でも，何十回でも，何百枚でも竹中明夫（国立環境研）プログラミング環境＋実行環境
統計解析関数群

描画関数群

プログラム作図のすすめ
まずは描いてみる
高水準作図関数と低水準作図関数
繰り返し作業をプログラムで画像の保存

この話の目指すところ
× Rのプログラムで絵が描けるようになる○ Rのプログラムで絵が描けそうな気になる◎ Rのプログラムで絵を描きたくなる
やる気にさえなれば，世の中にはさまざまな情報がある．

プログラミングの心構え
Required efforts
15 20 25 30

楽をするための苦労は惜しまない
手作業

510

楽
プログラム

0苦労

0510

152025

Amount of job

30

作図プログラムを書いてしまえば…
• 多量のデータでも片っ端から同じ形式でグラフ化できる• デザインをちょっと変えての書き直しも簡単• データにまちがいが見つかってもめげずに描き直せる片っ端からのグラフ化が最初の一歩相関係数

強い正の相関をひとつ発見

グラフにしてみると…
610261046261002w-2 2 6122x610

y2z0246-2 2610

ここにもあやしげなパターンが！

作図プログラムを書いてあー直せ，こー直せと言しまえば…
われても大丈夫• 多量のデータでも片っ端から同じ形式でグラフ化できる• デザインをちょっと変えての書き直しも簡単• データにまちがいが見つかってもめげずに描き直せる

作図プログラムを書いて締め切り間際にはとしまえば…
くに重要• 多量のデータでも片っ端から同じ形式でグラフ化できる• デザインをちょっと変えての書き直
しも簡単• データにまちがいが見つかってもめげずに描き直せる

プログラム作図のすすめ
まずは描いてみる
高水準作図関数と低水準作図関数
繰り返し作業をプログラムで画像の保存

「Ｒで自動作図」に必要な準備• R のインストール• 作業用ディレクトリの作成• 自分のデータ• テキストエディタ

タブかカンマ区切りのテキストファイル

Rに組込まれたエディタもあり(スクリプトの編集…）．私はシェアウエアの秀丸を愛用．サクラエディタ, K2Editorなど無料のものも多数．これらはプログラミング支援機能も充実）

Excelのファイルは，データそのものの他に，さまざまな情報が Excel だけが知っている
方法で書き込まれている．

テキストファイルは，文字で書かれた（人間がそのまま読める）情報のみが入っている

Excel で，テキストファイル形式で保存（一度に一枚のシートのみ）（メニュー）ファイル→ 「名前を付けて保存」
・ （ファイルの種類）
テキスト（タブ区切り） (*.txt)
ないしはCSV (カンマ区切り） (*.csv)
どちらもテキストファイル

実演タブ区切りカンマ区切り(CSV)

二通りの描き方• Rの入出力画面で描画関数を呼び出してグラフを描く• 描画に必要な命令を書き込んだファイ
ルを作り，これを呼び出してグラフを描く

まずは一枚描いてみる
leaves.txt
葉の長さ，幅，面積，乾燥重量，個体Rの入出力画面でデータの読み込み
代入

ファイル名

1行めは項目名> d <- read.table("leaves.txt", header = T)
タブ区切りデータの読み込み用関数

変数 d は，データの塊．
data.frameという「クラス」の「オブジェクト」
この扱いに慣れることがRの第一歩

x と y を指定してグラフを描く# から後ろは無視．コ
メントを書くのに使う> plot(d$W, d$L) # 長さ vs 幅の撒布図
データフレーム d の，Ｗ という名前の列実
演

51015d$W
20102030

d$L4050x と y を指定してグラフを描く

20304050> plot(d$Tree, d$L) # 木毎の葉の長さ

10

実
演
AB

C

> plot(d$W, d$L) # 長さ vs 幅の撒布図

302030201010d$L

40405050> plot(d$Tree, d$L) # 木毎の葉の長さ

5101520A

BCd$W

plot()に渡すデータの型が違うと，描かれるグラフも違う．

データの型
実数
複素数
論理値
文字列（因子）その他のクラス

さらに…
ベクトル（１次元）
行列（２次元）
配列（多次元）リスト（異種データを束ねたもの）
x1 <- 13x2 <- c(1, 3, 5)

おいおい慣れます．
期待した動作をしないとき，型の問題を疑ってみよう．

y <- c("A", "BB")※数値ひとつも長さ１のベクトル関数 plot()に渡すデータの型が違うと，描かれるグラフも違う．
• 渡されたデータの型により，実際の作業を行う描画関数が選択される．
• 描画関数のなかで，データの型により違う動作が選択される．
↑とりあえずは気にしない．plot() が魔法の呪文でないことだけ分かればＯＫ．

• Rの入出力画面で描画関数を呼び出してグラフを描く• 描画に必要な命令を書き込んだファイ
ルを作り，これを呼び出してグラフを描く

組込みのスクリプト編集エ
ディタないしはお好きなテ
キストエディタでプログラムを書いたテキストファイルを用意し…
ploｔ01.R (テキストファイル)d <-read.table("leaves.txt", header = T)plot(d$W, d$L)

Rの入出力画面から呼び出す．
> source("plot01.R")実
演プログラム作図のすすめ
まずは描いてみる
高水準作図関数と低水準作図関数
繰り返し作業をプログラムで画像の保存

Ｒの作図関数には高水準と低水準がある
高水準作図関数：一枚の絵を作る．呼び出すと座標系が設定される．
低水準作図関数：高水準作図関数で描いた図に点や線や字を書き加える．既存の座標系に従う．
なんら自虐的あるいは侮蔑的な意味はこめられていない

高水準作図関数でお手軽に作図好きなように組み合わせて低水準作図関数で自由に作図

d <-read.table(“leaves.txt”, header = T)plot(d)

高水準

1504001.0

2.54051510L8005W

6000L_W

240A

2.50Wd

1.0Tree
10400600

024実演

適当な高水準作図関数を使えば楽ができる．
＋ きめ細かい指定は• 描画関数呼び出し時のオプション指定• グローバルな描画パラメータの指定(par)plot(d$W, d$L)

30
20
10d$L

4050

高水準

51015d$W20

そっけない…

描画関数でよく使うオプション指定の例
col 色
pch 点のタイプ
cex 図中の字や点の大きさ
lty 線のタイプ
lwd 線の太さ
xlim, ylim 軸の最小・最大log 対数軸の指定...
※詳しくはマニュアル・ヘルプなど参照par() 関数で設定するオプションの例
mar, グラフの余白mfcol, 画面の分割（１ページに複数の絵を描く）...
例：
par(mar = c(5, 6, 2, 2))par(mfcol = c(2, 2))※詳しくはマニュアル・ヘルプなど参照par(mar=c(5, 6, 2, 2))010

Leaf length (cm)
20 30 40 50 60

plot(d$W, d$L, xlab = "Leaf width (cm)", ylab = "Leaflength (cm)", cex = 2, pch = 20, col = 4, cex.lab = 1.5,cex.axis = 1.5, xlim =c(0, 25), ylim = c(0, 60))0510152025
Leaf width (cm)

60504030
20100

これで，Treeの種類(A, B, C)
別に色分け

Leaf length (cm)plot(d$W, d$L, xlab = "Leaf width (cm)",ylab = "Leaf length (cm)", cex = 2, pch = 20,xlim =c(0, 25), ylim = c(0, 60),
col = c("red", "green", "blue")[d$Tree])

0

5

10

1520

25

Leaf width (cm)ちょっと面倒ですが，一応ご説明．
> c("red", "green", "blue")[1][1] "red"

3要素ベクトルの１番め> c("red", "green", "blue")[c(1, 3, 2)][1] "red" "blue" "green"
添字もベクトルに> d$Tree[1] A A A B B C C A B C C A A B C C B B A A A B B
B C C C A B C C A B C C B C AA C C B B
d$Treeは因子
Levels: A B C> as.numeric(d$Tree)[1] 1 1 1 2 2 3 3 1 2 3 3 1 1 2 3 3 2 2 1 1 1 2 2 2 3331233123323113322
数値(ベクトル)として評価

すぐに納得できなくてもよいです．
> c("red", "green", "blue")[c(1, 3, 2)][1] "red" "blue" "green"
d$Treeは因子> as.numeric(d$Tree)[1] 1 1 1 2 2 3 3 1 2 3 3 1 1 2 3 3 2 2 1 1 1 2 2 2 3331233123323113322> c("red", "green", "blue")[d$Tree]"red" "red" "green" "green" "blue" "blue" "red""green" "blue" ....
ベクトルXの添字に因子ベクトルを書くと，各因子のレベルに対応した（ベクトルXの）要素が並んだベクトルが得られる．

plot(d$W, d$L, xlab = "Leaf width (cm)",ylab = "Leaf length (cm)", cex = 2, pch = 20,
xlim =c(0, 25), ylim = c(0, 60),
col = c("red", "green", "blue")[d$Tree])

ベクトルの添字にベクトル
col = c("red", "red", "red", "green", "green", "blue","blue", "red","green" ...)[c(1,1,1,2,2,3,3,3,1,2,..)]
それを添字に

6050403020100ベクトルの添
字にベクトルLeaf length (cm)plot(d$W, d$L, xlab = "Leaf width (cm)",ylab = "Leaf length (cm)", cex = 2, pch = 20,
xlim =c(0, 25), ylim = c(0, 60),
col = c("red", "green", "blue")[d$Tree])05101520

Leaf width (cm)

25

60
20

30

40

50

A
B
C

10

実演

0

凡例を書き加える低水準
作図関数

Leaf length (cm)plot(d$W, d$L,... ,col = c("red", "green", "blue")[d$Tree])legend("topleft", levels(d$Tree),col=c("red", "green", "blue"), pch = 20, cex = 1.8)0510152025

Leaf width (cm)

こんな定跡もあります# 高水準で枠だけ描く(座標系が設定される)
plot(0, 0, type = 'n', xlim = c(0, 10),ylim = c(0, 100), xlab = "...", ylab = "...")# そのあと，線を引いたり点を打ったり多角形を描いたり文字を書いたり．
lines(x, y, …)
注意：高水準関数でグラフを描いた
points(x, y, …)
あと，続けて高水準関数を呼び出しpolygon(x, y, ...)ても，普通は上書きできません
text(x, y, "...")（※curve() など例外あり)

低水準作図関数を組み合わせれば（原理的には）なんでも書ける．
これも Ｒ で描きました実演プログラム作図のすすめ
まずは描いてみる
高水準作図関数と低水準作図関数
繰り返し作業をプログラムで画像の保存

• Rの入出力画面で描画関数を呼び出してグラフを描く• 描画に必要な命令を書き込んだファイ
ルを作り，これを呼び出してグラフを描く

プログラム中で作業の繰り返しを指示すれば，何枚もの絵を一度に描ける

今さら言うまでもありませんが，単純作業の繰り返しはコンピューターがもっとも得意とするところ．

Rでの繰り返し構造の表現方法
for (変数名 in ベクトル） {処理}while (条件) {処理}repeat {処理}(+ next, break)※構造化定理どんな計算手順も，「順次・反復・分岐」の組み合わせで記述できる

for (...）{# ファイルごとの繰り返しファイル名を設定する．
ファイルの内容を読み込む．
読んだデータを使って絵を描く}

for (...）{ # ファイルごとの繰り返しファイル名を設定する．
ファイルの内容を読み込む．
読んだデータを使って絵を描く}• ファイル名をプログラム中に書き並べる．
• ファイル名を規則的に生成する• ディレクトリ中のファイルを調べる• ファイル名を書き並べたファイルを読む• ．．．．

sites <- c("A", "B", "Tenjin", "Hakata") # 4つのサイト
n.block <- 100# 100 ブロックn.pot <- 50# ポットが50個# 20,000ポットそれぞれのデータファイルを読んで描画
for (site in sites) {for (i in 1:n.block) {for (j in 1:n.pot) {file <- sprintf("%s_B%03d_P%03d.txt", site, i, j)d <- read.table (file, header = T)
# 描画など…
}
}
たとえば…
}

90個の方形区内の木本の実生，約3,000個体余りの３年間の高さ成長のグラフ集めたデータはまずはグラフ化して眺めるべきだが…

手作業で3000個体の成長を90個のブロックごとにグラフにする気になるか？

集めたデータはまずはグラフ化して眺めるべきだが…
そんな簡単なことはコンピューターにだってできます．
手作業で3000個体の成長を90個のブロックごとにグラフにする気になるか？

調査データの管理と図化：私の場合• データを表計算ソフトで入力（久保さんには内緒）

自作の道具も• テキストファイルに変換• 必要に応じてPerlで整形

実
演• Rで作図par(ask = T)-1.0 -0.5 0.00.5

1.010021520

Height100
1520

Height0.0 0.5 1.0-1.0

AC
M
RZ

1

2003.02004.02005.02003.02005.0100
51

2003.02004.02005.02003.0

200

1151

1

5100

Height100

2004.0Year

1020

Height5Year

2005.0

200

8Year

1

2004.02004.020

Height100
52005.09

2003.02003.0Year

11

2004.020100

2005.0720

Height201006YearHeight

2004.0Year

5HeightYear

2003.0100
51

2003.020

2004.0520

Height100
511

2003.0

200

Year

420

Height20

100

35Height

Year

2004.02003.02004.0Year

2005.02003.02004.0Year200

# ブロックごとの，全個体の高さ成長# 2008-03-07 Rev. TAKENAKA, A.
# １ページのグラフ数，余白などの設定
par(mfrow = c(4,3))par(mar =c(4, 4, 1, 1) )par(mex = 0.80)# 種ごとの名前と色分け
sp.color <- c("magenta", "blue", "grey", "black", "green")
sp.name <- c('A', 'C', 'M', 'R', 'Z')
# 凡例用に空のプロットをひとつ．
plot(0, 0, type = 'n', xlab = "", ylab = "")legend("center", sp.name, col = sp.color, lwd = 2, lty = 1)

n.blocks <- 150 # ブロック番号はたかだかここまで．
for (i.block in 1:n.blocks) {# 各ブロックごとに…

file.name = sprintf("_%03d.txt", i.block)
if (file.access(file.name) == -1) { # 該当ファイルなし
next# 次のブロックへ}
d <- read.table(file.name, header = TRUE)
plot(1, 1, type = 'n', xlab = "Year", ylab = "Height", log="y",ylim = c(1, 300), xlim = c(2003, 2005)) # 枠だけ描画
text(2003.2, 250, i.block) # ブロック名を書き込む．
for (i in 1:nrow(d)) { # 個体ごとに…
# ※高さ成長を描く（次項）}}for (i in 1:nrow(d)) { # 個体ごとに…
if (d$h2[i] > 0) { # 2年めに生きている
if (d$h3[i] > 0) { # ３年めも生きてるなら，実線でlines(c(2003, 2004, 2005), c(d$h1[i], d$h2[i], d$h3[i]),col = sp.color[match(d$sp[i], sp.name)],lwd = 1, lty = 1)
} else { # ３年めまでに死亡なら，破線でlines(c(2003, 2004), c(d$h1[i], d$h2[i]),col = sp.color[match(d$sp[i], sp.name)], 色指定
lwd = 1, lty = 2)}線の指定}
text(2003.2, 250, i.block) # ブロック名を書き込む．
}

プログラム作図のすすめ
まずは描いてみる
高水準作図関数と低水準作図関数
繰り返し作業をプログラムで画像の保存

ベクトル画像とビットマップ画像
ベクトル：図の描き方の情報
PostScript, eps, Windowsメタファイル，PDF, …
• 拡大・縮小してもきれい．
• 多くの場合，データサイズが小さい• 描画に時間がかかることがある

ビットマップ：画素ひとつひとつの色情報（png, jpeg, bmp, GIF,…）• 拡大・縮小でみにくくなる．
• データサイズが大きくなりがち（画像によるが）

画像の保存・描画window 上に描かれた図をメタファイルとして保存するか，クリップボードにコピーし，適当なアプリケーションに渡して保存する．

多数の絵を描くならこちら．

実演

・画像ファイルを描画デバイスとして開いたあと描画を実行すると，ファイルに絵が書き込まれる．

描画デバイスのいろいろ

描画画面

windows(width = …, height = …, )win.metafile(filename, …)
postscript(filename, … )pdf(filename, …)
ひとつのファイル
png(filename, …)にたくさんの絵をjpeg(filename, …)
bmp(filename, …)…

描けて便利たとえば> d <- read.table(“leaves.txt”, header = T)
> pdf(“test.pdf”)> plot(d)> plot(d$L, d$W)
> plot(d$L ~ d$Tree)> dev.off()実
演先程の90区画のグラフ
もPDFファイルに．

実演

今日の話は「基礎の基礎」の入門「基礎の基礎」は拙頁にもあります．
他にもネット上の情報や書籍いろいろあります．
描画関数，描画ライブラリもいろいろありますプログラミングの心構え
Required efforts
15 20 25 30

楽をするための苦労は惜しまない
手作業

510

楽
プログラム0苦労

05

10152025

Amount of job

そんな簡単なことはコンピューターにだってできます．
30

Required efforts
10 15 20 25 30

資産の蓄積と慣れ・習熟で苦労はどんどん小さくなる

苦労

05楽！

苦労
苦労…?

0

5

1015

2025

30

Number of figures楽をするための苦労は惜しまない

清聴多謝