| Top Page | プログラミング | R 自動化 目次 | 索引 | 前へ | 次へ |

R でプログラミング:データの一括処理とグラフ描き

13. 見栄えのよいグラフ(その2):複数の図と軸の説明(+ 日本語の表示)

updated on 2009-03-31

この章では,複数のグラフを並べた図に,見栄えよく軸の説明などを描く方法を紹介します (できあがり参考例).

並べた図にきれいに軸の説明をつける

まずは並べる

ひとつの作図画面(ないしは作図デバイス)に複数のグラフを並べるには, すでに 6章 で説明したように,par で mfrow や mfcol というパラメータに 値を設定します.

前の章で使ったのと同じ, w_h_data.txtを使います.このファイルには "Q. nana と Q. hatena という二種類の木の サイズ(太さと高さ)の情報が書かれています.前の章では一枚のグラフに二種のデータを 重ねてプロットしました.こんどは,それぞれ別のグラフに描いて並べてみます. 個々のグラフを描くための設定は前の章の最後と同様です. 二つのグラフを横に並べるので,描画画面はやや横長にして, windows(width = 7, height = 5) として開いた描画画面を用意して 試してみました(>グラフ).

d <- read.table ('w_h_data.txt', header = TRUE, sep = "\t")  # データの読み込み

par(mfrow = c(1, 2))          #  描画画面を1行2列に分けて使う(横に二つ並べる)
par(mar = c(5.5, 6, 4.1, 2))  #  余白の広さを行数で指定.下,左,上,右の順.
par(mgp = c(4, 1.2, 0))       #  余白の使い方.説明,ラベル,軸の位置を行で指定.
par(lwd = 2)   #  線の太さを指定.

for (i in 1:2) {  # 2種類それぞれについて...

    dd <- d[as.numeric(d$sp) == i,]  #  因子 sp が,i番めの水準であるものだけ取り出す.
    sp <-levels(dd$sp)[i]            #  その水準の値(この場合,種名の文字列)

    plot(dd$w, dd$h, pch = 16,
        xlab = "Diameter at breast height (cm)",
        ylab = "Tree height (cm)",
        cex = 2.5,              #  記号の大きさを設定する(標準は1)
        cex.lab = 2.0,          #  軸の説明の字の大きさを設定する
        cex.axis = 1.8,         #  軸の数字等(ラベル)の大きさを設定する
        cex.main = 1.8,         #  メインタイトルの字の大きさを設定する
        xlim = c(0, 30),        # x 軸の両端の値 (座標系を決める)
        xaxp  = c(0, 30, 3),    # x 軸の両端の tick の,座標系上の位置と,間隔の数
        ylim = c(0, 1800),      # y 軸の両端の値 (座標系を決める)
        yaxp  = c(0, 1500, 3))  # y 軸の両端の tick の,座標系上の位置と,間隔の数

    par(font = 3)  # イタリック
    legend ("topleft", legend = sp, cex = 1.4, bty = "n") # 記号や線種を指定しない
    par(font = 1)  # イタリックを解除
}

legend で,記号や線種のパラメータを指定していないので, 文字だけ(この場合は種名)だけが書かれています.

この例はとうてい見栄えがよいとは言えません.x軸の文字が隣同士で重なりあってしまっています. 文字を小さくすれば重なりは避けられますが,こんどは読みにくくなるでしょう. このような場合,グラフひとつづつに軸の説明をつけず,まとめてひとつの説明で済ませれば 見栄えがよくなるはずです.

個々の図の説明は書かず,外側に余白を作る.

まずは,個々のグラフで軸の説明を書くのをやめるとともに,作図領域の外側に空白を作ります (>グラフ). 字や記号の大きさは微調整してあります.

d <- read.table ('w_h_data.txt', header = TRUE, sep = "\t")  # データの読み込み

par(oma = c(2.5, 3, 3, 0))    #  デバイス領域内で,作図領域の外に余白をとる.

par(mfrow = c(1, 2))          #  描画画面を1行2列に分けて使う(横に二つ並べる)
par(mar = c(3, 3, 2, 1))
par(mgp = c(4, 1.2, 0))       #  余白の使い方.説明,ラベル,軸の位置を行で指定.
par(lwd = 2)   #  線の太さを指定.

for (i in 1:2) {  # 2種類それぞれについて...

    dd <- d[as.numeric(d$sp) == i,]  #  因子 sp が,i番めの水準であるものだけ取り出す.
    sp <-levels(dd$sp)[i]            #  その水準の値(この場合,種名の文字列)

    plot(dd$w, dd$h, pch = 16,
        xlab = "", ylab = "",
        cex = 2.5,              #  記号の大きさを設定する(標準は1)
        cex.axis = 1.6,         #  軸の数字等(ラベル)の大きさを設定する
        cex.main = 1.8,         #  メインタイトルの字の大きさを設定する
        xlim = c(0, 30),        # x 軸の両端の値 (座標系を決める)
        xaxp  = c(0, 30, 3),    # x 軸の両端の目盛の,座標系上の位置と,間隔の数
        ylim = c(0, 1800),      # y 軸の両端の値 (座標系を決める)
        yaxp  = c(0, 1500, 3))  # y 軸の両端の目盛の,座標系上の位置と,間隔の数

    par(font = 3)
    legend ("topleft", legend = sp, cex = 1.4, bty = "n") # 記号や線種を指定しない
    par(font = 1)
}

まず,plot で,xlab = "", ylab = "" として,軸の説明を 何も書かないようにします.また,mar の設定を変えて,個々のグラフの軸の説明のために 余白をとるのをやめます.

一番のポイントは一行め,oma の設定です.おそらく outer margin の略でしょう. まず,5章の 「3つの領域」のところで説明した,プロット領域,作図領域の関係を想いだしてください. 特に設定しないと,デバイス領域全体が作図領域になります. oma を使うと,作図領域の外側に余白をとることができます. 下,左,上,右の余白の行数を示す4つの要素が並んだ数値ベクトルを設定します. 上の例では,順に 2.5行,3行,3行,0行の余白をとっています.

作図領域の外に文字を書く

ではいよいよ,余白領域に文字を書きます.プロット領域内に文字を書くときは text を使いますが,プロット領域の外や,さらに作図領域の外に 文字を書くには mtext という専用の関数を使います. 最初の m は,margin の m でしょう (>グラフ).

d <- read.table ('w_h_data.txt', header = TRUE, sep = "\t")  # データの読み込み

par(oma = c(2.5, 3, 3, 0))    #  デバイス領域内で,作図領域の外に余白をとる.

par(mfrow = c(1, 2))          #  描画画面を1行2列に分けて使う(横に二つ並べる)
par(mar = c(3, 3, 2, 1))
par(mgp = c(4, 1.2, 0))       #  余白の使い方.説明,ラベル,軸の位置を行で指定.
par(lwd = 2)   #  線の太さを指定.

for (i in 1:2) {  # 2種類それぞれについて...

    dd <- d[as.numeric(d$sp) == i,]  #  因子 sp が,i番めの水準であるものだけ取り出す.
    sp <-levels(dd$sp)[i]            #  その水準の値(この場合,種名の文字列)

    plot(dd$w, dd$h, pch = 16,
        xlab = "", ylab = "",
        cex = 2.5,              #  記号の大きさを設定する(標準は1)
        cex.axis = 1.6,         #  軸の数字等(ラベル)の大きさを設定する
        cex.main = 1.8,         #  メインタイトルの字の大きさを設定する
        xlim = c(0, 30),        # x 軸の両端の値 (座標系を決める)
        xaxp  = c(0, 30, 3),    # x 軸の両端の目盛の,座標系上の位置と,間隔の数
        ylim = c(0, 1800),      # y 軸の両端の値 (座標系を決める)
        yaxp  = c(0, 1500, 3))  # y 軸の両端の目盛の,座標系上の位置と,間隔の数

    par(font = 3)
    legend ("topleft", legend = sp, cex = 1.4, bty = "n") # 記号や線種を指定しない
    par(font = 1)
}

mtext("Height vs DBH relationships of two oak species",
      outer = TRUE,      # 作図領域の外の余白に書く
      side = 3,          # 上の余白に書く
      cex = 1.8,         # 字の大きさ
      line = 0.5)        # 外に向かって 0.5行離れたところに書く.

mtext("Diameter at breast height (cm)",
      outer = TRUE,      # 作図領域の外の余白に書く
      side = 1,          # 下の余白に書く
      cex = 1.8,         # 字の大きさ
      line = 1)          # 外に向かって 1行離れたところに書く.

mtext("Tree height (cm)",
      outer = TRUE,      # 作図領域の外の余白に書く
      side = 2,          # 左の余白に書く
      cex = 1.8,         # 字の大きさ
      line = 1)          # 外に向かって 1行離れたところに書く.

mtext は,「外側」専門の文字列描画関数です.プロット領域の外側で,作図領域の内側 (軸のラベルや説明が書かれる領域)に書くには outer = FALSE, 作図領域の外側で,デバイス領域の内側 に書くには outer = TRUEを指定します.何も指定しないと FALSE だと見なします. 上の例では,ふたつのグラフを描いた作図領域の外側に文字を書きたいので, outer = TRUE としています.

上下左右のどこの余白に書くかは side で指定します.下からはじめて時計回りで 1 から 4に対応します. lineは,内側の領域(outer = TRUE なら作図領域)からどれだけ離れたところに文字列を 書くかを行数で指定します.0 ならすぐ外側になります. 最初の oma の指定とすりあわせつつ,適当な行数を指定します.


補遺1.軸のラベルを90度回転させる

軸のラベル(数字など)の向きを 変えることができます.これはlas というパラメータで制御します. parで設定することもできるし,plot のパラメータで 指定することもできます.可能な値は 0 (標準・軸に平行), 1 (x軸,y軸とも水平), 2 (x軸,y軸とも軸に垂直),3 (x軸,y軸とも垂直(半時計回りで90度回転)) の4つです. plot(......, las = 3) と設定して描いた例を載せておきます (>グラフ). x軸のラベルが90度回転していることが分かります.x軸のラベルが文字列で,水平に書くと隣と 重なってしまう場合に便利でしょう.

補遺2.日本語の出力

※ここでの説明は,Windows 環境,R が 2.5 以上の版で確認しています. 非Windows環境や,あまり古い版の R の場合,ここに書かれていることが あてはまらないこともあります.

作図画面での日本語表示

作図画面に描くグラフの軸の説明などに日本語を使うと,問題なくそのまま表示されます. xlab = "胸高直径 (cm)"などとして試してください.

ビットマップとしての扱い

作図画面にグラフを描き,その画面がアクティブになった状態で,Gui 画面のメニューで [ファイル]→[別名で保存する]を選ぶと,ファイル形式を選択して保存することができます. png, jpg, bmp といったビットマップファイルに記録する際に, 当然ながら日本語表示に影響はありません. 描いたグラフを画素の並びとして記録するだけですから当然です. 作図デバイスとしてビットマップ画像ファイルを指定して書込む場合も同様です.

ベクトルデータとしての扱い

一方,ベクトル画像(画素の並びではなく,線の引き方など描画方法の集合として画像を表現) としての扱いは少々面倒で,いわゆる文字化けが生じるケースが多々あります. 下に,OS が Windows XP Professional, R が 2.8.1 の場合をまとめた 表を載せました.フォントのインストール状況によっては違った振る舞いをするかもしれません.

描画画面に表示された図をコピー・保存(参考:4章
処理 日本語の表示
メタファイルとしてクリップボードにコピーして他のソフトのファイルに貼り付け ×; 文字化け
PDF, postscriptに保存 ×; 文字化け or エラー
メタファイル(*.emf) に保存 ○; 作成したファイルを他ソフトのファイルに貼り付けて使える.ただし貼り付け後に 編集しようとすると文字化け

画像ファイルを作図デバイスとして書込む(参考:4章
出力ファイル
カッコ内は作成関数
日本語の表示
PDF (pdf) ○; par(family = ...) で日本語フォントを指定すれば可. 指定しないと文字化け※
postscript (ps) ×; 日本語フォントを指定しないと文字化け,指定するとエラー
メタファイル(win.metafile) ○; 作成したファイルを他ソフトのファイルに貼り付けて使える.ただし貼り付け後に 編集しようとすると文字化け
※pdf で使えるフォントは Japan1, Japan1GothicBBB, Japan1HeiMin など. 例;par (family = "Japan1")

まとめ

これらを踏まえて,基本的な方針を整理すると,

ということになります.

ビットマップデータをプレゼンファイルに貼り付ける場合は, 縮小・拡大による劣化を避けるため, width や height を指定して実際に使う大きさのファイルを作るのがよいでしょう.

PDF作成時に par(family = ...) で日本語フォントを指定する場合, 作図パラメータを設定する時はつねにそうですが, PDF ファイルを作図デバイスとして用意してからフォント指定をしないと有効にならないことに 注意してください.下にごく簡単な例を示します (作成されるPDFファイル).

pdf("test.pdf")                  # PDF ファイルを作図デバイスとして用意.
par(family = "Japan1GothicBBB")  # ゴチックを指定
par(mar = c(5, 5, 3, 2))         # 余白
plot(0:10, 0:10, type = "p",     # type = "p" で,撒布図
     main = "日本語のメインタイトル", cex.main = 2,  # メインタイトルとその大きさ
     xlab = "x軸", ylab = "y軸", cex.lab = 2)        # 軸の説明とその大きさ
dev.off()                        # ファイルを閉じる


| Top Page | プログラミング | R 自動化 目次 | 索引 | 前へ | 次へ |