55. 複数の図


画面分割・複数の図

R では一つのデバイスに複数の図を描くことが出来る.

以下に出てくるパラメータの説明はグラフィックスパラメータと割り付けパラメータの節で扱っている.

画面(デバイス)を分割して図を描く

まず,画面(デバイス)の外周の余白を指定するパラメータがどこにあるかを紹介する.

タイトルや注釈テキストを入れる場合で,余白を指定する場合は par() の引数に以下のパラメータを入れて指定する.タイトルや注釈テキストを入れない場合は指定する必要は無い.ここで紹介する例では,全体のタイトルを描くため,まず oma で上部に 4 mex 分(mex の初期値は 1 なので 4 文字分)の余白を取っている.

 
 par(oma = c(0, 0, 4, 0))   # 下・左・上・右の順で余白を設定

画面(デバイス)を分割するパラメータは以下の様なものがある.

引数

関数

mfcol = c(m,n), mfrow = c(m,n)

画面を m 行 n 列に分割する.mfcol で指定した場合は列順に,mfrow で指定した場合は行順にグラフが描かれる.1画面に戻す場合は mfrow=c(1,1) または mfcol=c(1,1) とすればよい.

mfg = c(i,j,m,n)

画面を m 行 n 列に分割している場合で,左上から順番に図を描きたくない場合に使う.次のグラフを i 行 j 列にを描く.

fig = c(4,9,1,4)/10

現在の画面における現在の図表の位置を指定するパラメータで,ページ内の任意の位置に図表をおくためのものである.値は百分率を指定し,「左側・右側・底辺・上側」の順に指定する.例の値はページの右下に図を置くように指定している.

ここでは画面を 2 × 2 に分割する.

 
 par(mfrow=c(2,2)) 

画面が分割できたら,グラフを 1 つずつ描けば,複数のグラフが(行順に)一度に表示される出力が得られる.

 
 plot(sin)
 plot(cos)
 plot(asin)
 plot(acos)

最後に outer = T と指定してから mtext を使うことで全体のタイトルを外周に書き込む.

 
 mtext(side = 3, line=1, outer=T, text = "Title", cex=2)

すると左下図のようになる.ここで最初の余白 (oma) を設定していなければ右下図のようにタイトルがはみ出すことになる.

 

 

少し高度な画面(デバイス)分割

上で紹介したグラフィックスパラメータ mfrow や mfcol を用いることで画面を複数に分割することが出来るのだが,以下で紹介する関数を用いることで規則的な画面分割に限らず,自由に画面を分割することが出来るようになる.

layout()を用いた画面分割

関数 layout() を用いると,行列 mat で行数と列数を指定して画面を分割することが出来る.このとき画面は『行列の行数 $\times$ 行列の列数』に分割され,行列の成分が作図の順番となる. 

 
 mat <- matrix(c(1,0,2,2), 2, 2, byrow = TRUE)
 mat                    

     [,1] [,2]           # このとき画面 (デバイス) は
[1,]    1    0           # ( 1 番目の図)   (ここは空白のまま)
[2,]    2    2           # ( --------- 2 番目の図 --------- )

 layout(mat)            # と分割される
 plot(sin) 
 plot(cos) 

layout.show(n) でデバイス番号を確認することが出来,また lcm(x) で長さを指定することも出来る.

 
 layout(matrix(c(1,3,2,2), 2, 2, byrow = TRUE), respect=T, widths=lcm(5), heights=lcm(5))
 plot(sin)
 plot(cos)
 plot(acos)

split.screen()を用いた画面分割

関数 split.screen() に長さ 2 のベクトル c( m, n ) を引数に与えることで画面を分割することも出来る.分割された画面には番号が振られ,その番号(画面)を指定して図を描くことができる.

例えば,画面を上下 2 つに分割する場合は以下のようにする. この場合は上側が画面番号 1 ,下側が画面番号 2 になる.

 
 split.screen(c(2,1))

[1] 1 2 

行列を引数にしても画面分割を行うことも出来る.

ここで引数 screen に分割する画面番号を指定することによって,その画面をさらに分割することも出来る.例えば上の例で出来た画面 2 をさらに 3 つに分割してグラフを描く.

 
 split.screen(c(1,3), screen = 2)

[1] 3 4 5

 screen(1); plot(rnorm(10))             # 画面 1 にプロット
 screen(3); plot(rnorm(10), type="l")   # 画面 3 にプロット
 screen(4); plot(rnorm(10), type="S")   # 画面 4 にプロット
 screen(5); plot(rnorm(10), type="h")   # 画面 5 にプロット

以下の出力結果で括弧つきの番号は画面番号を表す (実際の出力には表示されない) .

画面消去をする場合は関数 frame() で消去することが出来る.関数 erase.screen() は図を消去するのではなく,背景色で塗りつぶすだけなのでメモリを食うので使用は控えた方が良い.また,通常の 1 画面形式に戻る場合は,関数 close.screen(all=T) を実行すればよい.