本文へスキップ
からだにいいもの

Rのトピックスを中心に『まだ、まだ、知らない、役に立つ情報?』を発信します。

Rで解析:gridパッケージのプロットをお手軽に「gridExtra」パッケージの紹介

Rのgridグラフィックスは描画の自由度が高い一方、複数の図を1ページに並べたり、データフレームを表として描いたりする定型作業は自前で組む必要があります。gridExtraパッケージは、この手間のかかる作業をgtableベースのコマンド群で解決します。arrangeGrobとgrid.arrangeはlayout_matrixで各図の行と列を直接指定でき、marrangeGrobは図が多いときに自動で複数ページへ分割します。tableGrobはデータフレームや行列をそのまま表のグラフィックオブジェクトに変換し、ttheme_defaultで文字サイズや余白をまとめて制御できます。さらにngonGrobとellipseGrobで正多角形や楕円も描画可能です。gridオブジェクトのほか、ggplot2やlatticeのオブジェクトもグラフィックオブジェクトへ変換してくれます。

パッケージバージョンは2.3.1。Windows 11 x64 (build 26200)のR version 4.6.1で確認しています。

パッケージのインストール

下記コマンドを実行してください。

# パッケージのインストール
install.packages("gridExtra")
# パッケージの読み込み
library("gridExtra")
# コマンド例の実行に必要なパッケージの読み込み
library("grid")
スポンサーリンク

コマンド例

詳細はコメント、パッケージのヘルプを確認してください。

gridの世界では、描画される要素はすべてグラフィックオブジェクト(grob)として扱われます。gridExtraはこのgrobを対象に、複数のgrobを格子状に配置するarrangeGrob系、データフレームを表のgrobに変換するtableGrob系、正多角形や楕円のgrobを作るngonGrob系という3系統のコマンドを提供します。arrangeGrobやtableGrobはgtableオブジェクトを作成します。gtableオブジェクトはgrid.drawコマンドでプロットが可能です。

複数のグラフィックオブジェクトを1ページに配置:arrangeGrobコマンド

複数のgrobをレイアウト行列に従って配置したgtableを作成します。描画は行わないため、作成したgtableをgrid.drawに渡してプロットするか、さらに別のレイアウトの部品として使えます。

オプション意味初期値
grob、gtable、ggplot、trellisのオブジェクトを可変長で指定なし
grobs配置するgrobのリストを指定list(…)
layout_matrix配置位置を表すレイアウト行列を指定(省略可)なし
vp描画に用いるビューポートを指定NULL
namegtableのname引数に渡す値“arrange”
as.table論理値、TRUEで左下から右上、FALSEで左上から右下の順に配置TRUE
respectgtableのrespect引数に渡す値FALSE
clipgtableのclip引数に渡す値“off”
nrowgtableのnrow引数に渡す値で行数を指定NULL
ncolgtableのncol引数に渡す値で列数を指定NULL
widthsgtableのwidths引数に渡す値で各列の幅を指定NULL
heightsgtableのheights引数に渡す値で各行の高さを指定NULL
top上側に配置する文字列またはgrobを指定(省略可)NULL
bottom下側に配置する文字列またはgrobを指定(省略可)NULL
left左側に配置する文字列またはgrobを指定(省略可)NULL
right右側に配置する文字列またはgrobを指定(省略可)NULL
padding注釈の周囲に確保する余白を長さ1のunitで指定unit(0.5, “line”)
### データ例を作成#####
# パネルに表示するラベル
panel_label <- c("Site-A", "Site-B", "Site-C", "Site-D")

# パネルの背景色
panel_fill <- c("#F7D6A0", "#BFD8C4", "#C7CDE8", "#EBC6C6")

# 背景の矩形とラベル文字を重ねたgrobをリストとして作成
panel_list <- mapply(function(lab, bg) {
  grobTree(rectGrob(gp = gpar(fill = bg, col = "white", lwd = 2)),
           textGrob(lab, gp = gpar(fontsize = 14)))}, 
  panel_label, panel_fill, SIMPLIFY = FALSE)
########

# 1番目を上段全幅、2番目と3番目を中段に並べ、4番目を下段全幅にするレイアウト行列を作成
panel_layout <- rbind(c(1, 1), c(2, 3), c(4, 4))

# レイアウト行列に従って配置したgtableを作成(この時点では描画されない)
g_arrange <- arrangeGrob(grobs = panel_list,
                         layout_matrix = panel_layout,
                         top = "arrangeGrob layout",
                         padding = unit(1, "line"))

# 新しい描画ページを用意
grid.newpage()

# 作成したgtableを描画
grid.draw(g_arrange)

配置したレイアウトをプロット:grid.arrangeコマンド

arrangeGrobと同じ引数を受け取り、作成したgtableをプロットします。

オプション意味初期値
arrangeGrobに渡すgrobおよび引数を可変長で指定なし
newpage論理値、TRUEで新しいページを開いてから描画TRUE
# 3つの矩形grobを1行に並べ、上下に見出しを付けてプロット
grid.arrange(rectGrob(gp = gpar(fill = "#F2C14E", col = NA)),
             rectGrob(gp = gpar(fill = "#78B7A0", col = NA)),
             rectGrob(gp = gpar(fill = "#8FA6D8", col = NA)),
             nrow = 1,
             top = "grid.arrange",
             bottom = "three panels in one row",
             newpage = TRUE)

# widthsで幅の比率を2対1に変えてプロット(列数はwidthsで決まる)
grid.arrange(rectGrob(gp = gpar(fill = "#F2C14E", col = NA)),
             rectGrob(gp = gpar(fill = "#78B7A0", col = NA)),
             widths = c(2, 1),
             newpage = TRUE)

・3つの矩形grobを1行に並べ、上下に見出しを付けてプロット

・widthsで幅の比率を2対1に変えてプロット(列数はwidthsで決まる)

複数ページに分割して配置:marrangeGrobコマンド

grobの個数が1ページに配置できる数を超える場合、同じレイアウトを繰り返し適用してページ単位に分割しプロットします。

オプション意味初期値
grobs配置するgrobのリストを指定なし
arrangeGrobに渡す引数を可変長で指定なし
ncol1ページあたりの列数を指定なし
nrow1ページあたりの行数を指定なし
layout_matrix1ページ分の配置位置を表すレイアウト行列を指定matrix(seq_len(nrow * ncol), nrow = nrow, ncol = ncol)
top各ページ上部に表示する見出しを式または文字列で指定quote(paste(“page”, g, “of”, npages))
# 6枚分のgrobをオリジナルデータとして作成
page_grobs <- lapply(1:6, function(i) {
  grobTree(rectGrob(gp = gpar(fill = "grey95", col = "grey60")),
           textGrob(paste0("panel ", i), gp = gpar(fontsize = 14)))})

# 1ページあたり2行2列で分割した配置リストを作成
g_multi <- marrangeGrob(page_grobs, nrow = 2, ncol = 2)

# 分割されたページ数を確認
length(g_multi)

# 新しい描画ページを用意
grid.newpage()

# 1ページ目を描画
grid.draw(g_multi[[1]])

# 新しい描画ページを用意
grid.newpage()

# 2ページ目を描画
grid.draw(g_multi[[2]])

・1ページ目を描画

・2ページ目を描画

正多角形を描画する:ngonGrobコマンド

中心座標と頂点数を指定して、単位円に内接する正多角形のgrobを作成します。頂点数や大きさ、回転角、縦横比はベクトルで与えることができ、その場合は中心座標の個数に合わせて繰り返し適用されます。作成と描画を同時に行うgrid.ngonコマンドも収録されています。

オプション意味初期値
x図形の中心のx座標をunitで指定なし
y図形の中心のy座標をunitで指定なし
n頂点の数を指定5
size外接円の半径を指定5
phase最初の頂点のx軸からの角度をラジアンで指定pi/2
angle多角形全体の回転角をラジアンで指定0
ar縦横比を指定1
gp線と塗りつぶしの書式をgparで指定gpar(colour = “black”, fill = NA, linejoin = “mitre”)
polygonGrobに渡す追加の引数を指定なし
position.units座標に用いる既定の単位を指定“npc”
size.units大きさに用いるgridの単位を指定“mm”
# 描画する正多角形の頂点数をオリジナルデータとして作成
ngon_n <- c(3, 4, 6, 8)
# 図形を並べるx座標を等間隔で作成
ngon_x <- seq(0.15, 0.85, length.out = length(ngon_n))
# 図形の塗りつぶし色を作成
ngon_col <- c("#E29578", "#83C5BE", "#F4D06F", "#8FA6D8")
# 頂点数の異なる正多角形をまとめた1つのgrobを作成
g_ngon <- ngonGrob(x = unit(ngon_x, "npc"),
                   y = unit(rep(0.5, length(ngon_n)), "npc"),
                   n = ngon_n,
                   size = 12,
                   gp = gpar(fill = ngon_col, col = "grey20"))
# 新しい描画ページを用意
grid.newpage()
# 正多角形のgrobを描画
grid.draw(g_ngon)

# 同じ配置に回転角と縦横比の変化を加えたgrobを作成
g_ngon_var <- ngonGrob(x = unit(ngon_x, "npc"),
                       y = unit(rep(0.5, length(ngon_n)), "npc"),
                       n = ngon_n,
                       size = 12,
                       angle = seq(0, pi / 2, length.out = length(ngon_n)),
                       ar = c(1, 0.5, 2, 1),
                       gp = gpar(fill = ngon_col, col = "grey20"))
# 新しい描画ページを用意
grid.newpage()
# 回転と縦横比を変えたgrobを描画
grid.draw(g_ngon_var)

########
# 新しい描画ページを用意
grid.newpage()
# grid.ngonを使うとgrobの作成と描画を一度に実行できる
grid.ngon(x = unit(0.5, "npc"), y = unit(0.5, "npc"),
          n = 7, size = 30, gp = gpar(fill = "#83C5BE", col = "grey20"))

・正多角形のgrobを描画

・回転と縦横比を変えたgrobを描画

・grid.ngonを使うとgrobの作成と描画を一度に実行できる

楕円をプロット:ellipseGrobコマンド

n個の頂点で円を近似したうえでarとangleにより変形させた楕円のgrobを作成します。arで扁平の度合いを、angleで傾きを指定します。作成と描画を同時に行うgrid.ellipseも用意されています。

オプション意味初期値
x楕円の中心のx座標をunitで指定なし
y楕円の中心のy座標をunitで指定なし
size外接円の半径を指定5
angle楕円全体の回転角をラジアンで指定pi/4
ar縦横比を指定1
n楕円の近似に用いる頂点の数を指定50
gp線と塗りつぶしの書式をgparで指定gpar(colour = “black”, fill = NA, linejoin = “mitre”)
polygonGrobに渡す追加の引数を指定なし
position.units座標に用いる既定の単位を指定“npc”
size.units大きさに用いるgridの単位を指定“mm”
# 楕円の中心のx座標
ell_x <- c(0.25, 0.50, 0.75)

# 楕円の中心のy座標
ell_y <- c(0.35, 0.60, 0.35)

# 楕円の傾き
ell_angle <- c(pi / 6, 0, -pi / 6)

# 傾きと扁平の度合いを指定した楕円のgrobを作成
g_ellipse <- ellipseGrob(x = unit(ell_x, "npc"),
                         y = unit(ell_y, "npc"),
                         size = 22,
                         ar = 0.35,
                         angle = ell_angle,
                         gp = gpar(fill = c("#E29578", "#83C5BE", "#8FA6D8"),
                                   col = "grey20"))

# 新しい描画ページを用意
grid.newpage()

# 楕円のgrobを描画
grid.draw(g_ellipse)

########
# 新しい描画ページを用意
grid.newpage()
# grid.ellipseを使うとgrobの作成と描画を一度に実行できる
grid.ellipse(x = unit(0.5, "npc"), y = unit(0.5, "npc"),
             size = 35, ar = 2, angle = pi / 3,
             gp = gpar(fill = "#F4D06F", col = "grey20"))

・楕円のgrobを描画

正多角形の頂点座標を取得:polygon_regularコマンド

単位円に内接する正多角形の頂点座標を2列の行列として返します。始点と終点が同じ座標になるため、行数は頂点数に1を加えた値になります。ngonGrobの内部でも使われており、座標を自分で加工したい場合に便利です。

オプション意味初期値
n頂点の数を指定5
phase最初の頂点のx軸からの角度をラジアンで指定0
# 単位円に内接する正六角形の頂点座標を取得
hex_xy <- polygon_regular(n = 6)

# 取得した座標を確認(始点と終点が同じ座標になり閉じた形になる)
hex_xy
       [,1] [,2]
[1,]  6.123032e-17  1.0
[2,] -8.660254e-01  0.5
[3,] -8.660254e-01 -0.5
[4,] -1.836910e-16 -1.0
[5,]  8.660254e-01 -0.5
[6,]  8.660254e-01  0.5
[7,]  3.061516e-16  1.0

# 行数と列数を確認
dim(hex_xy)

# 開始角度を30度ずらした正六角形の頂点座標を取得
hex_rot <- polygon_regular(n = 6, phase = pi / 6)

# 取得した座標を確認
hex_rot
   [,1]          [,2]
[1,] -0.5  8.660254e-01
[2,] -1.0  3.330669e-16
[3,] -0.5 -8.660254e-01
[4,]  0.5 -8.660254e-01
[5,]  1.0 -7.216450e-16
[6,]  0.5  8.660254e-01
[7,] -0.5  8.660254e-01

データフレームを表としてプロット:tableGrobコマンド

データフレームや行列の各セルを文字のgrobに変換し、格子状に並べたgtableを返します。rowsやcolsにNULLを渡すと行名や列名の行を省略できます。作成と描画を同時に行うgrid.tableも用意されています。

オプション意味初期値
d表として描画するデータフレームまたは行列を指定なし
rows行名として表示するベクトルを指定(省略可)rownames(d)
cols列名として表示するベクトルを指定(省略可)colnames(d)
theme表の書式をまとめたテーマのリストを指定ttheme_default()
vp描画に用いるビューポートを指定(省略可)NULL
gtableの制御に用いる追加の引数を指定なし
# 表データを作成
obs_data <- data.frame(site = c("Kyoto", "Shiga", "Tokyo"),
                       temp = c(21.4, 20.8, 19.6),
                       rain = c(112.5, 98.0, 143.2),
                       stringsAsFactors = FALSE)

# データフレームをそのまま表のgtableに変換
g_table <- tableGrob(obs_data)

# 新しい描画ページを用意
grid.newpage()

# 表のgtableを描画
grid.draw(g_table)

########
# 行名を省略し、列名を任意の文字列に置き換えた表のgtableを作成
g_table_named <- tableGrob(obs_data,
                           rows = NULL,
                           cols = c("Site", "Temp (C)", "Rain (mm)"))

# 新しい描画ページを用意
grid.newpage()

# 列名を差し替えた表を描画
grid.draw(g_table_named)

# 新しい描画ページを用意
grid.newpage()

# grid.tableを使うと表の作成と描画を一度に実行できる
grid.table(obs_data, rows = NULL)

表の書式をまとめて指定:ttheme_defaultコマンド

tableGrobのthemeに渡す書式のリストを作成します。文字サイズ、文字色、フォントファミリー、セル内の余白をまとめて指定でき、返り値のリストを直接書き換えて個別の要素を上書きすることもできます。背景の塗りつぶしと罫線を持たないttheme_minimalも同じ引数構成で用意されています。

コマンド例内のobs_dataは先のtableGrobコマンドの例で作成します。

オプション意味初期値
base_size既定の文字サイズを指定12
base_colour既定の文字色を指定“black”
base_family既定のフォントファミリーを指定“”
parse論理値、TRUEで文字列をplotmathの式として解釈FALSE
paddingセル内の水平方向と垂直方向の余白を長さ2のunitで指定unit(c(4, 4), “mm”)
テーマの各要素を上書きする追加の引数を指定なし
# 文字サイズと文字色、セル内の余白を変更したテーマを作成
my_theme <- ttheme_default(base_size = 10,
                           base_colour = "#20304A",
                           padding = unit(c(6, 3), "mm"))

# 作成したテーマを適用した表のgtableを作成
g_theme <- tableGrob(obs_data, rows = NULL, theme = my_theme)

# 新しい描画ページを用意
grid.newpage()

# テーマを適用した表を描画
grid.draw(g_theme)

########
# 背景と罫線を持たない最小限のテーマを適用した表のgtableを作成
g_minimal <- tableGrob(obs_data, rows = NULL,
                       theme = ttheme_minimal(base_size = 10))

# 新しい描画ページを用意
grid.newpage()

# 最小限のテーマを適用した表を描画
grid.draw(g_minimal)

複数の表を結合する:gtable_rbindコマンド

複数のgtableを縦方向に結合します。列数が一致している必要があり、列幅はsizeの指定に従ってそろえられます。横方向に結合するgtable_cbindも同じ引数構成で、こちらは行数が一致している必要があります。行名や列名を手がかりに位置合わせをしてから結合するgtable_combineも用意されています。

オプション意味初期値
結合するgtableを可変長で指定なし
size幅と高さの決め方を”max”、”min”、”first”、”last”から指定“max”
z重ね合わせ順序を表すz値を指定(省略可)NULL
# 上側に置く表のgtableを作成
tbl_upper <- tableGrob(obs_data[1:2, ], rows = NULL,
                       theme = ttheme_default(base_size = 10))

# 下側に置く表のgtableを作成
tbl_lower <- tableGrob(obs_data[3, ], rows = NULL, cols = NULL,
                       theme = ttheme_minimal(base_size = 10))

# 2つの表を縦方向に結合し、列幅は最大値にそろえる
g_rbind <- gtable_rbind(tbl_upper, tbl_lower, size = "max")

# 新しい描画ページを用意
grid.newpage()

# 縦方向に結合した表を描画
grid.draw(g_rbind)

########
# 左側に置く表のgtableを作成
tbl_left <- tableGrob(obs_data[, c("site", "temp")], rows = NULL,
                      theme = ttheme_default(base_size = 10))

# 右側に置く表のgtableを作成
tbl_right <- tableGrob(obs_data[, "rain", drop = FALSE], rows = NULL,
                       theme = ttheme_default(base_size = 10))

# 2つの表を横方向に結合し、行の高さは最大値にそろえる
g_cbind <- gtable_cbind(tbl_left, tbl_right, size = "max")

# 新しい描画ページを用意
grid.newpage()

# 横方向に結合した表を描画
grid.draw(g_cbind)

・縦方向に結合した表を描画


この記事が誰かの役に立ちますように。

スポンサーリンク
価格および配送状況は変更される場合があります。購入時は商品ページをご確認ください。
当サイトに表示されている商品情報はAmazonから提供されたものであり、更新または削除される場合があります。
karada-goodはAmazonアソシエイトとして、適格販売により収入を得ています。