#author("2023-01-13T17:43:16+09:00","","")
SIZE(25){COLOR(red){grid パッケージ事始}}

* COLOR(orange){とりあえず} [#qefa4d47]

[[Paul Murrell 先生のホームページ:http://www.stat.auckland.ac.nz/~paul/]] をご覧下さい.この頁の内容は grid パッケージのヘルプと Paul Murrell 先生のホームページにある PDF ファイルの内容を参考にして作成しました.

* COLOR(green){グリッド・グラフィックスとは} [#u8175c38]

グリッド・グラフィックスパッケージ(grid graphics package)は,R のグラフィックスパッケージ
とは別に用意されている標準 R グラフィックス・パッケージである.
ユーザーは作図デバイス上で任意の長方形の表示域(viewports)を定義し,
各表示域の多くの座標系を定義することが出来る.
グリッド・グラフィックスの利点は,R の graphics パッケージでは自由度に制限があった
カスタマイズが自由に出来る点である.graphics パッケージ中の高水準作図関数や
低水準作図関数では十分な作図が得られない時に力を発揮し,例えば lattice 
パッケージ中の作図関数にはグリッド・グラフィックス中の関数が頻繁に使われている.
以下に特徴を挙げる.
- 作図のカスタマイズが容易に行える.
- グラフィックス出力の道具として「線・長方形・円・多角形・データの記号」が用意されている.
- 現在位置(current location)という概念があり,1 回の作図ごとに作図領域
(Graphics Regions)と座標系(Coodinate Systems)を作成・調節することが出来る.
- グラフィックス・オブジェクト(grob)という概念があり,実際に作図すること無しに
グラフィックス用のオブジェクトをカスタマイズすることが出来る.
- ただし,グリッド・グラフィックスと標準 R グラフィックスを混在させることは好ましくないらしい.

* COLOR(green){グリッド・グラフィックス事始} [#p6f0216d]

まず,グリッド・グラフィックスのパッケージを呼び出す.

 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                              # 関数定義

#ref(grid パッケージ事始/grid-01.gif, center)

* COLOR(blue){グラフィックス出力関数} [#pc85c486]

関数 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 軸を描く       |

* COLOR(purple){作図領域と座標系} [#yfb9b0d5]

グリッド・グラフィックスを行うときは,作図領域(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 回の作図ごとに作図領域を指定することで,
より柔軟な作図を実現している.

#ref(grid パッケージ事始/grid-02.gif, center)

作図領域オブジェクトがどのような作図領域になっているかを見る場合は,
関数 grid.show.viewport() を使用する.

 grid.show.viewport(vp1)
 grid.show.viewport(vp2)

#ref(grid パッケージ事始/grid-03.gif, center)

* COLOR(black){座標系と単位} [#o43c3de5]

関数 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()

#ref(grid パッケージ事始/grid-04.gif, center)

単位の種類は以下の通り.
| 単位        | 説明|
| "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)へ線を引く

* COLOR(red){グリッド・グラフィックスパラメータ} [#w0f7b0d6]

作図領域およびグラフ式のオブジェクトはすべてグリッド・グラフィックスパラメータ(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()

#ref(grid パッケージ事始/grid-05.gif, center)

* COLOR(orange){レイアウト} [#gad8b010]

作図領域をいくつかの行と列に分割することが出来,分割する幅や高さを指定することも出来る.

 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)

#ref(grid パッケージ事始/grid-06.gif, center)

実際の作図例は以下の通り.以下では 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)

#ref(grid パッケージ事始/grid-07.gif, center)

* COLOR(green){grobの作成} [#x7ff0b66]

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"))             # 赤に変更

#ref(grid パッケージ事始/grid-08.gif, center)

「線を引く」という grob を生成し,次にこの grob を作図デバイスに出力する.

 grid.newpage()
 line <- linesGrob()
 grid.draw(line)

#ref(grid パッケージ事始/grid-09.gif, center)

grob である "line" を関数 editGrob() で編集し,色を緑に変更する.

 line <- editGrob(line, gp=gpar(col="green"))
 grid.draw(line)

#ref(grid パッケージ事始/grid-10.gif, center)

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 を青に変更

#ref(grid パッケージ事始/grid-11.gif, center)

関数 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")

#ref(grid パッケージ事始/grid-12.gif, center)

* COLOR(green){オブジェクトのセーブ・ロード} [#jde300ec]

作図をファイルに保存する場合は関数 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 を呼び出す

* COLOR(blue){グリッド・グラフィックスを使った作図例} [#l7727994]

(いろいろ投稿していただけますと幸いです)

お言葉に甘えて,使い方の例だけ

 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))
 }

#ref(grid パッケージ事始/cardioid.png)

数式も書けます

 grid.newpage()
 grid.text(expression(z[i] == sqrt(x[i]^2 + y[i]^2)),
           gp=gpar(cex=2))

#ref(grid パッケージ事始/math.gif)

正方形を描いてみました.

 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))

#ref(grid パッケージ事始/square.gif)

* COLOR(purple){ご意見など} [#ted200f8]

いろいろご意見をいただけますと幸いです.間違い修正・改善などを施していただけますと嬉しいです.(作成者:舟尾 暢男)
->お言葉に甘えて,使い方の例だけ~
早速,使い方の例を示していただきましてありがとうございます.いや〜,非常に綺麗なカージオイドですねぇ〜!--  &new{2004-12-26 (日) 13:13:13};
-関数 radian() の定義が抜けていたようなので,勝手ながら関数定義を追加させていただきました(関数 radian() の定義は青木先生のサイト内「[[図形描画関数群:http://aoki2.si.gunma-u.ac.jp/R/plot.html]]」から引用しました). --  &new{2004-12-26 (日) 13:26:39};

#comment

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS