grid パッケージ事始
Paul Murrell 先生のホームページ をご覧下さい.この頁の内容は grid パッケージのヘルプと Paul Murrell 先生のホームページにある PDF ファイルの内容を参考にして作成しました.
グリッド・グラフィックスパッケージ(grid graphics package)は,R のグラフィックスパッケージ とは別に用意されている標準 R グラフィックス・パッケージである. ユーザーは作図デバイス上で任意の長方形の表示域(viewports)を定義し, 各表示域の多くの座標系を定義することが出来る. グリッド・グラフィックスの利点は,R の graphics パッケージでは自由度に制限があった カスタマイズが自由に出来る点である.graphics パッケージ中の高水準作図関数や 低水準作図関数では十分な作図が得られない時に力を発揮し,例えば lattice パッケージ中の作図関数にはグリッド・グラフィックス中の関数が頻繁に使われている. 以下に特徴を挙げる.
まず,グリッド・グラフィックスのパッケージを呼び出す.
library(grid)
デモは関数 grid.plot.and.legend() で見ることが出来る.この関数の関数定義を見ることで, グリッド・グラフィックスを用いた作図の手順を見ることが出来る.
grid.multipanel(vp=viewport(0.5, 0.5, 0.8, 0.8)) # デモ(1) grid.plot.and.legend() # デモ(2) grid.plot.and.legend # 関数定義
関数 grid.newpage() で,作図デバイスを初期化(全消去)することが出来る. 新しく作図を行う場合や,直前までの作図を全て消去したい場合に用いる.
grid.newpage()
作図デバイスを初期化した後はいろいろ作図を行うわけだが,グリッド・グラフィックスにも R の graphics パッケージの低(高)水準作図関数と似たような関数が用意されている. 以下の関数のオプション draw は,全て TRUE になっている.
grid.arrows(x = c(0.25, 0.75), y = 0.5) | 矢印を描く |
grid.circle(x=0.5, y=0.5, r=0.5) | 円を描く |
grid.frame(name=NULL, gp=gpar(), vp=NULL) | 枠を描く |
grid.grill(h = seq(0.25, 0.75, 0.25), v = seq(0.25, 0.75, 0.25)) | 網を描く |
grid.lines(x = c(0.25, 0.75), y = 0.5) | 線を描く |
grid.line.to(x=1, y=1) | 線を描く |
grid.points(x, y) | データを点で描く |
grid.polygon(x=c(0, 0.5, 1, 0.5), y=c(0.5, 1, 0.5, 0)) | 多角形を描く |
grid.rect(x = 0.5, y = 0.5, width = 0.7, height = 0.3) | 長方形を描く |
grid.segments(x0 = 0, y0 = 0, x1 = 0.5, y1 = 0.5) | 線分を描く |
grid.text(label="abc", x = 0.5, y = 0.5) | 文字列を描く |
grid.xaxis(at = NULL, label = T, main = T, name = NULL) | x 軸を描く |
grid.yaxis(at = NULL, label = T, main = T, name = NULL) | y 軸を描く |
グリッド・グラフィックスを行うときは,作図領域(Graphics Regions)と座標系 (Coordinate Systems)を常に意識する必要がある.作図領域を作成するには関数 viewport() を用いる.ちなみに viewport は「表示域」という意味である.
viewport(x=座標, y=座標, width=幅, height=高さ, just = "center"))
作図領域は,まず領域の中心の ( x 座標,y 座標 ) を指定し,次に領域の幅と高さを指定する.
デフォルトでは領域の中心が基準点となっているが,基準点を左下にする場合は引数に
「just=c("left", "bottom")」を指定する.また,座標領域を回転させる場合は引数「angle=角度」
を指定すればよい.
作図領域(viewport)は生成された順に木構造(時には入れ子構造)を成す.よって,
複数の作図領域を生成しておいて,作図途中に任意の作図領域を呼び出すことが出来る.また,
現在使っている作図領域が不要になった場合は,その作図領域を破棄することも出来る.
これらの動作はそれぞれ関数 pushViewport(),popViewport() で行う.
作図領域 viewport は木構造になっているので,作図領域を pop(破棄)する代わりに,
関数 upViewport(上に上がる階層数) と downViewport(木の下にある作図領域オブジェクト名)
で作図領域を操作することも出来,seekViewport(オブジェクト名) で作図領域を探すことも出来る.
関数 current.viewport() で viewport の構造を見ることも出来る.
.
pushViewport( viewport オブジェクト) # viewport の呼び出し popViewport( viewport オブジェクト) # viewport の破棄
例として,まず vp1 というオブジェクトに作図領域を代入し,作図デバイスに push (呼び出し)する.次に,作図領域 vp1 に x 軸や y 軸などを描いた後,vp1 を pop(破棄)する
grid.newpage() vp1 <- viewport(x=0.5, y=0.5, w=0.8, h=0.8, xscale=c(0,10), yscale=c(0,10)) pushViewport(vp1) # vp1 を呼び出す grid.rect() # 長方形で囲む grid.xaxis() # x 軸を描く grid.yaxis() # y 軸を描く popViewport() # vp1 を破棄する
続いて,vp2 というオブジェクトに作図領域を代入し,作図デバイスに push (呼び出し)する.次に,作図領域 vp2 に x 軸や y 軸などを描いた後,vp2 を pop(破棄)する.
vp2 <- viewport(x=0.5, y=0.5, w=0.2, h=0.2, xscale=c(0,10), yscale=c(0,10)) pushViewport(vp2) # vp2 を呼び出す grid.rect() # 長方形で囲む grid.points(x=1:10, y=1:10) # vp2 に点を 10 個描く grid.xaxis() # x 軸を描く grid.yaxis() # y 軸を描く popViewport() # vp2 を破棄する
vp1 と vp2 にはほぼ同じ作図を施したのだが,vp2 が vp1 よりも小さめの作図領域であるため, さも大小 2 つの座標軸が出来上がっているかのような出力となっている.このように, グリッド・グラフィックスでは1 回の作図ごとに作図領域を指定することで, より柔軟な作図を実現している.
作図領域オブジェクトがどのような作図領域になっているかを見る場合は, 関数 grid.show.viewport() を使用する.
grid.show.viewport(vp1) grid.show.viewport(vp2)
関数 unit() で座標系に関する単位を決める.これにより,作図領域を作成する際により細かい 指定が行える(最も使われるのは "npc" である).以下に関数 unit() の使用例を示す.
unit(1, "npc") unit(1:3/4, "npc") unit.c(unit(0.5,"npc"), unit(1,"mm")+unit(0.2,"cm"))
実際,viewport() に指定する場合は以下の様にする.
pushViewport( viewport(xscale=c(0,100)) ) pushViewport( viewport(x=unit(50, "native"), y=unit(0.5, "npc"), w=stringWidth("A example of Coodinates"), h=unit(3, "lines")) ) grid.rect() popViewport()
単位の種類は以下の通り.
単位 | 説明 |
"npc" | 左下を (0, 0),右上を (1, 1) とした標準座標 |
"native" | 位置と大きさを現在の表示域(current viewport)に合わせる |
"inches" | 左下を (0, 0) として,inch 単位で座標を決める |
"cm" | 左下を (0, 0) として,cm で座標を決める |
"mm" | 左下を (0, 0) として,mm で座標を決める |
"points" | 左下を (0, 0) として,points(1/72.27 inches)で座標を決める |
"bigpts" | 左下を (0, 0) として,bigpts(1/72 inches)で座標を決める |
"picas" | 左下を (0, 0) として,picas(12 points)で座標を決める |
"dida" | 左下を (0, 0) として,dida(1157/1238 points)で座標を決める |
"cicero" | 左下を (0, 0) として,cicero(12 didas)で座標を決める |
"scaledpts" | 左下を (0, 0) として,scaledpts(65536 points)で座標を決める |
"char" | 位置と大きさを現在の fontheight に合わせる |
"lines" | 位置と大きさを文字列の高さ(現在の fontheight と lineheight に依存)に合わせる |
"snpc" | 左下を (0, 0),右上を (1, 1) として,現在の表示域(current viewport)よりも小さめの位置と大きさにする |
"strwidth" | 位置と大きさを与えられた文字の幅(文字と現在の fontsize に依存)に合わせる |
"strheight" | 位置と大きさを与えられた文字の高さ(文字と現在の fontsize に依存)に合わせる |
"grobwidth" | 位置と大きさを与えられた grob の幅(現在の grob の状態に依存)に合わせる |
"grobheight" | 位置と大きさを与えられた grob の高さ(現在の grob の状態に依存)に合わせる |
座標つきのグラフを作るときには、"native" をよく使う。 grid.point() 関数の場合は、default.unit="native" であるため、unitを意識せずに、散布図を作成できる。 それ以外の関数はほとんど default.unit="npc" であるため、座標上の希望位置に作図するには unit を変更せねばならない。 以下は、xy座標の(1,1)から(2,3)に線分を引く例。
grid.newpage() vp1 <- viewport(xscale=c(0,10), yscale=c(0,10), w=0.9, h=0.9 ) #縦横10目盛の座標 pushViewport(vp1) # 座標設定を呼び出し grid.xaxis() # x軸を描く grid.yaxis() # y軸を描く grid.lines(c(1,2),c(1,3), default.unit="native") #(1,1)から(2,3)へ線を引く
作図領域およびグラフ式のオブジェクトはすべてグリッド・グラフィックスパラメータ(gpar) を含んでいる.作図領域が「作図領域スタック」に push される際や,グラフ式の オブジェクトが描かれる際に,現在指定している gpar の設定が反映される. 使い方や概念は,普通のグラフィックスパラメータとほぼ同様である.
gpar() # グラフィックスパラメータの指定 get.gpar(names = NULL) # パラメータ情報の取得 get.gpar() # 現在の全グラフィックスパラメータ情報の取得
以下に一覧を示す.
名前 | 機能 |
col | 線とボーダーの色 |
fill | 塗りつぶしの色(例:rectangles,polygons) |
lty | 線の形式 |
lwd | 線の太さ(線のサイズ:fontsize × cex × lineheight) |
fontsize | フォントサイズ(単位はポイント) |
cex | フォントサイズの倍率 |
fontfamily | フォントファミリー(例:HersheySerif) |
fontface | フォントの種類(1 = plain, 2 = bold, 3 = italic, 4 = bold italic) |
lineheight | 線の高さ(テキストサイズ=fontsize × cex の比で指定) |
font | フォント |
グリッド・グラフィックスパラメータの使用例として,作図領域を 2 種類の色の枠で囲う例を示す.
pushViewport( viewport(gp=gpar(fill="grey")) ) grid.rect() grid.rect(w=0.8, h=0.6, gp=gpar(fill="white")) grid.text("inner rectangle", y=0.75) grid.text("outer rectangle", y=0.05) popViewport()
作図領域をいくつかの行と列に分割することが出来,分割する幅や高さを指定することも出来る.
grid.layout(行数, 列数, width, height, ... ) viewport( layout=grid.layout(行数, 列数, width, height, ... ) )
以下に作図領域を分割する例を示す.引数 respect=T で幅と高さの比を適度に調節している. また,作図領域がどのようなレイアウトになっているかを見る場合は,関数 grid.show.layout() を使用する.
grid.newpage() gl <- grid.layout(2, 3, respect=T, h=unit(c(0.5, 1, 2), c("cm", "null", "mm")) ) grid.show.layout(gl)
実際の作図例は以下の通り.以下では 3 × 4 に分割した領域を生成して領域を長方形で囲んだ後, 分割した領域の一部分を作図領域としてから領域を長方形で囲んでいる.
grid.newpage() pushViewport( viewport(layout=grid.layout(3, 4)) ) grid.rect(gp=gpar(col="grey")) grid.segments( c(1:3/4, rep(0,2)), c(rep(0,3), 1:2/3), c(1:3/4, rep(1,2)), c(rep(1,3), 1:2/3), gp=gpar(col="grey") ) pushViewport( viewport(layout.pos.col=2:3, layout.pos.row=2) ) grid.rect() popViewport(2)
R の graphics パッケージ中の関数ならば,作図の命令を行えば直ちに作図が行われる. 一方,グリッド・グラフィックスには grob(Grid Graphics Objects:グリッド・グラフィックスオブジェクト) という概念がある.これは作図に関する情報をオブジェクトという形にすることが出来, このオブジェクトを直ちに作図デバイスに出力することも出来るし, いろいろと加工した後に作図デバイスに出力することも出来る.これもグリッド・グラフィックス の柔軟性を支える屋台骨となっている.grob を作成する関数は以下が用意されている.
arrowsGrob(x = c(0.25, 0.75), y = 0.5) | 矢印を描く |
circleGrob(x=0.5, y=0.5, r=0.5) | 円を描く |
frameGrob(name=NULL, gp=gpar(), vp=NULL) | 枠を描く |
linesGrob(x = c(0.25, 0.75), y = 0.5) | 線を描く |
lineToGrob(x=1, y=1) | まず最初に,関数 moveToGrob(x, y) で現在位置(current location)を決める必要がある |
pointsGrob(x, y) | データを点で描く |
polygonGrob(x=c(0, 0.5, 1, 0.5), y=c(0.5, 1, 0.5, 0)) | 多角形を描く |
rectGrob(x = 0.5, y = 0.5, width = 0.7, height = 0.3) | 長方形を描く |
segmentsGrob(x0 = 0, y0 = 0, x1 = 0.5, y1 = 0.5) | 線分を描く |
textGrob(label, x = 0.5, y = 0.5) | 文字を描く |
xaxisGrob(at = NULL, label = T, main = T, name = NULL) | x 軸を描く |
yaxisGrob(at = NULL, label = T, main = T, name = NULL) | y 軸を描く |
grob を編集する基本関数は grid.edit() である.また,関数 grid.draw(grobの名前) で
grob を出力することが出来,関数 gTree() でいくつかの grob をグループ化し,
それらを単一のオブジェクトとして扱うことが出来る.
関数 grid.edit() の簡単な使用例を挙げる.
grid.newpage() grid.xaxis(name="xa", vp=viewport(w=.5, h=.5)) # x 軸 grid.edit("xa", gp=gpar(col="red")) # 赤に変更
「線を引く」という grob を生成し,次にこの grob を作図デバイスに出力する.
grid.newpage() line <- linesGrob() grid.draw(line)
grob である "line" を関数 editGrob() で編集し,色を緑に変更する.
line <- editGrob(line, gp=gpar(col="green")) grid.draw(line)
grob には grob の名前でアクセスすることも出来る.名前でアクセスする場合は, 関数 gPath() を用いる方法と,名前をそのまま指定する方法とがある.
grid.newpage() grid.lines(name="gl") grid.edit(gPath("gl"), gp=gpar(col="red")) # gl を赤に変更 grid.edit("gl", gp=gpar(col="blue")) # gl を青に変更
関数 grid.frame() を使う場合,まず grid.frame() で枠のオブジェクト(grob) を作成してから,次に関数 grid.pack() でオブジェクトを出力する.出力する際に,オプション gp で装飾を施す( gpar を変更する)ことが出来る.
grid.newpage() grid.frame(name="gf", draw=TRUE) grid.pack("gf", rectGrob(gp=gpar(fill="grey"))) grid.pack("gf", textGrob("hi there"), side="right")
作図をファイルに保存する場合は関数 save() を用いる.保存先は現在の作業ディレクトリで,フルパスを指定してもよい.
grid.newpage() grid.grill() # 網目を描く tmp <- recordPlot() # 現在の作図を tmp に代入 save(tmp, file="tmp-041123") # ファイル tmp-041123 に保存
ファイルに保存した作図をロードする場合は関数 load() を用いる.
load("tmp-041123") tmp # 保存した tmp を呼び出す
この操作は grob に対しても実行できる.
temp <- textGrob("Hello world.") save(temp, file="temp-041123") load("temp-041123") grid.draw(temp) # 保存した temp を呼び出す
(いろいろ投稿していただけますと幸いです)
お言葉に甘えて,使い方の例だけ
t <- seq(0, 360, by=5) radian <- function(degree) { degree/180*pi } l <- 0.18 ox <- l*cos(radian(t)) oy <- l*sin(radian(t)) grid.newpage() viewport(x=0.250,y=0.250,w=0.500,h=0.500) grid.rect() for (i in 1:length(t)) { grid.circle(ox[i]+0.65, oy[i]+0.5, sqrt((ox[i]-ox[1])^2+(oy[i]-oy[1])^2)) }
数式も書けます
grid.newpage() grid.text(expression(z[i] == sqrt(x[i]^2 + y[i]^2)), gp=gpar(cex=2))
正方形を描いてみました.
grid.newpage() pushViewport(viewport(w=.5, h=.5, name="A")) grid.rect() pushViewport(viewport(w=.5, h=.5, name="B")) grid.rect(gp=gpar(col="grey")) upViewport(2) grid.rect(vp="A", gp=gpar(fill="red")) grid.rect(vp=vpPath("A", "B"), gp=gpar(fill="blue")) grid.newpage() grid.polygon(x=c((0:4)/10, rep(.5, 5), (10:6)/10, rep(.5, 5)), y=c(rep(.5, 5), (10:6/10), rep(.5, 5), (0:4)/10), id=rep(1:5, 4), gp=gpar(fill=1:5))
いろいろご意見をいただけますと幸いです.間違い修正・改善などを施していただけますと嬉しいです.(作成者:舟尾 暢男)