Rで解析:ggplot2の文法のまま3Dプロット「ggcube」パッケージ
本パッケージは、3D対応のgeomとstat、coord_3dコマンドの座標系でggplot2の文法のまま3Dプロットが可能です。coord_3d()はpitch・roll・yawの3軸まわりの回転、透視投影と平行投影の切り替え、光源の向きや強さを指定する照明効果を1つの関数で制御することが可能です。さらに、animate_3dコマンドでは、プロットが回転するGIFや動画を書き出すことが可能です。
パッケージバージョンは0.2.0。Windows 11 x64 (build 26200)のR version 4.6.1で確認しています。
パッケージのインストール
下記コマンドを実行してください。library(“ggcube”)を実行すると自動で「ggplot2」パッケージが読み込まれます。
# パッケージのインストール
install.packages("ggcube")
# パッケージの読み込み(依存のggplot2も同時に読み込まれる)
library("ggcube")コマンド例
詳細はコメント、パッケージのヘルプを確認してください。
ggcubeの関数は、大きく4つの役割に分かれています。座標系を決めるcoord_3d()、データを立体に変換して描くgeom_bar_3d()やgeom_smooth_3d()などの3D用geom、z軸の目盛りや見た目を整えるscale_z_continuous()やテーマ要素、そして完成した図を回転させるanimate_3d()です。この順に組み合わせていくのが基本的な流れになります。
3D図形の中に注釈用の点・文字・線分を埋め込む:annotate_3dコマンド
実行すると、指定した3D座標に注釈が配置された図が得られます。ggplot2のannotate()が別レイヤーになるのに対し、annotate_3dで作った注釈は本体の図形と一緒に奥行き順でソートされるため、面の裏側に回り込んだ注釈が図形で正しく隠されます。
| オプション | 意味 | 初期値 |
|---|---|---|
| type | 注釈の種類を表す文字列。”point”、”text”、”segment”のいずれかを指定する | なし |
| … | 種類ごとのパラメータ。pointはx、y、z、textはx、y、z、label、segmentはx、y、z、xend、yend、zendが必須。色やサイズなどの装飾もここで指定する | なし |
### データ作成:中央が盛り上がった地形を模した格子データ #####
terrain <- expand.grid(x = seq(-3, 3, length.out = 40),
y = seq(-3, 3, length.out = 40))
# 中心からの距離に応じて高さを減衰させる
terrain$z <- 30 * exp(-(terrain$x^2 + terrain$y^2) / 4)
########
# ベースの3Dプロットを作成
p_annot <- ggplot(terrain, aes(x, y, z)) +
coord_3d(light = light(mode = "hsl", direction = c(-1, 0, 1)))
# 山頂に赤い点を1つ置く
p_annot + geom_surface_3d(
annotate = annotate_3d("point", x = 0, y = 0, z = 30,
color = "red", size = 4))
# ベクトルを渡すと、1回の呼び出しで複数の点を配置できる
p_annot + geom_surface_3d(
annotate = annotate_3d("point", x = seq(-2, 2, 1), y = 0,
z = 30 * exp(-seq(-2, 2, 1)^2 / 4),
color = "green", size = 3))
# 点・文字・線分を組み合わせて山頂を指し示す
p_annot + geom_surface_3d(
annotate = list(
annotate_3d("point", x = 0, y = 0, z = 30,
color = "red", size = 4),
annotate_3d("text", x = 0, y = 0, z = 30,
label = "Rは進化する", color = "red",
vjust = -1.2, fontface = "bold"),
annotate_3d("segment", x = 0, y = 0, z = 30,
xend = 0, yend = 0, zend = 0,
color = "red", linewidth = 1)))
回転・透視投影・縦横比を指定して3D座標系を作る:coord_3dコマンド
ggcubeで作図する際の中心となる関数です。既存のggplotオブジェクトに足すだけで立体表示になり、視点の回転、遠近感の強さ、立方体の縦横比、どの面を描くか、軸ラベルをどの辺に置くを、このコマンドで指定できます。
| オプション | 意味 | 初期値 |
|---|---|---|
| pitch | y軸まわりの回転角度(度)。正の値で手前の面が右向きに回る | 0 |
| roll | x軸まわりの回転角度(度)。正の値で手前の面が下向きに回る | -60 |
| yaw | z軸まわりの回転角度(度)。正の値で手前の面が時計回りに回る | -30 |
| persp | 透視投影を適用するかどうか。TRUEでは遠くの物体が小さく描かれ、FALSEでは平行投影になる | TRUE |
| dist | 視点からデータ立方体の中心までの距離。persp = TRUEのときのみ有効で、大きいほど遠近の歪みが小さい | 2 |
| expand | 軸範囲をデータ範囲より外側に広げるかどうか。TRUEのときはscale_x_continuous(expand = …)で調整できる | TRUE |
| clip | パネル外への描画の扱い。”off”を指定するとパネルの外側にも描画される | “off” |
| panels | 描画する面の指定。”background”、”foreground”のほか、”xmin”などの面名、”all”、”none”を指定できる | “background” |
| xlabels | x軸のラベルとタイトルを置く辺の指定。”auto”または隣接する2つの面名からなる長さ2の文字ベクトル | “auto” |
| ylabels | y軸のラベルとタイトルを置く辺の指定。指定方法はxlabelsと同じ | “auto” |
| zlabels | z軸のラベルとタイトルを置く辺の指定。指定方法はxlabelsと同じ | “auto” |
| title_position | 立方体の内側に置かれる軸タイトルの位置。”auto”は軸の手前端、”center”は軸の中央に配置する | c(“auto”, “center”) |
| rotate_labels | 軸ラベルを投影後の軸の向きに合わせて自動回転させるかどうか | TRUE |
| scales | 縦横比の決め方。”free”は各軸を独立に立方体いっぱいまで引き伸ばし、”fixed”はデータの比率を保つ | “free” |
| ratio | x、y、zの相対的な軸の長さを指定する長さ3の数値ベクトル | c(1, 1, 1) |
| zoom | 図全体の入り方を制御する数値。1より大きいと拡大、小さいと余白が増える | 1 |
| light | light()で作成した照明設定オブジェクト。”none”で照明を無効にできる | ggcube::light() |
| … | 内部処理のために予約された引数 | なし |
# ベースの3Dプロットを作成
p_coord <- ggplot(terrain, aes(x, y, z)) +
geom_surface_3d(color = NA) +
scale_fill_viridis_c() +
theme(legend.position = "none")
# 既定の視点で描画する
p_coord + coord_3d()
# 回転をすべて0にすると、x-y平面を真上から見た状態になる
p_coord + coord_3d(pitch = 0, roll = 0, yaw = 0)
# 3軸の回転を組み合わせて任意の角度から見る
p_coord + coord_3d(pitch = 25, roll = -50, yaw = 40)
# 視点を近づけて遠近感を強調する
p_coord + coord_3d(dist = 1)
# 透視投影を切ると、平行な線が平行のまま描かれる
p_coord + coord_3d(persp = FALSE)
# データの比率を保ったまま描画する
p_coord + coord_3d(scales = "fixed")
# z軸だけを2倍の長さに引き伸ばす
p_coord + coord_3d(ratio = c(1, 1, 2))
# 立方体の6面すべてを描く(手前の面は既定で20%の不透明度)
p_coord + coord_3d(panels = "all")
# 面を名前で選んで描画する
p_coord + coord_3d(panels = c("xmin", "ymin", "zmin"))
# 軸ラベルを置く辺を手動で指定する
p_coord + coord_3d(xlabels = c("ymax", "zmax"),
zlabels = c("xmax", "ymin"))
# 軸ラベルの自動回転を止めて水平に固定する
p_coord + coord_3d(rotate_labels = FALSE)
# 少し引きの構図にして余白を広げる
p_coord + coord_3d(zoom = 0.85)
・コード例の上から4つ目までのプロットを紹介

立方体の面と軸ラベルの見た目をthemeで整える:cube_themingコマンド
cube_themingは「ggcube」パッケージが追加するテーマ要素のヘルプページです。?cube_theming()で実行します。そうすると、ヘルプページが表示されます。
下記にヘルプページに記載のオプションをggplot2の「theme」コマンドで使った例を紹介します。
# 6面すべてを描いたうえで、面とラベルの体裁を細かく指定する
ggplot(terrain, aes(x, y, z)) +
geom_surface_3d(fill = "steelblue", color = "white", linewidth = 0.15) +
coord_3d(panels = "all") +
theme(
# 奥側の面の塗りと枠線
panel.background = element_rect(fill = "gray95", color = "gray40"),
# 手前の面はデータが隠れないよう強めに透過させる
panel.foreground = element_rect(alpha = 0.15),
# 手前の面のグリッド線
panel.grid.foreground = element_line(color = "gray70", linewidth = 0.25),
# 目盛りラベルの色
axis.text = element_text(color = "gray20"),
# z軸の目盛りラベルだけ色を変える
axis.text.z = element_text(color = "firebrick"),
# marginで軸タイトルの余白を広げる
axis.title = element_text(margin = margin(t = 20)),
# x軸タイトルだけ色を変える
axis.title.x = element_text(color = "steelblue4"))
度数集計やビニングを自動で行い3D棒グラフを描く:geom_bar_3dコマンド
データを集計した3次元の棒グラフをプロットするコマンドです。x軸とy軸が離散値なら組み合わせごとの度数を数え、連続値なら2次元のビンに区切って集計し、片方だけが連続値なら群を保ったままビンを設定します。ggplot2のgeom_bar()とgeom_histogram()のコマンドを3Dでプロットします。集計済みの高さを使いたい場合はgeom_col_3d()のコマンドを使います。
| オプション | 意味 | 初期値 |
|---|---|---|
| mapping | aes()で作成した審美的属性のマッピング | NULL |
| data | このレイヤーで表示するデータ | NULL |
| stat | 使用する統計変換 | StatBar3D |
| position | 位置調整の方法。position_on_face()を指定すると結果を1つの平面に畳み込める | “identity” |
| … | レイヤー関数に渡すその他の引数。colour、fill、linewidth、annotate = annotate_3d(…)などを指定する | なし |
| bins | 各次元のビン数。1つの値かc(x方向, y方向)の長さ2のベクトルで指定する。離散変数では無視される | 10 |
| binwidth | 各次元のビン幅。指定するとbinsより優先される。離散変数では無視される | NULL |
| drop | TRUEでは空のビンを描画しない。FALSEでは高さ0の柱として描画する | TRUE |
| width | ビン間隔に対する柱の幅の割合。1で柱同士が接し、1未満にすると隙間ができる | 1 |
| faces | 描画する面の指定。”all”、”none”、または”zmax”などの面名のベクトル | “all” |
| light | light()で作成した照明設定オブジェクト。”none”で無効、NULLで座標系の設定を継承する | NULL |
| cull_backfaces | 視点と反対を向いたポリゴンを描画から除くかどうか | TRUE |
| sort_method | 奥行きソートのアルゴリズム | NULL |
| scale_depth | 手前の線を太く、奥の線を細くするよう線幅を調整するかどうか | TRUE |
| force_convex | 凸包に含まれない頂点をポリゴンから除去するかどうか | FALSE |
| na.rm | FALSEのとき欠損値を取り除く | FALSE |
| show.legend | このレイヤーを凡例に含めるかどうか | NA |
| inherit.aes | FALSEのとき既定の審美的属性を上書きする | TRUE |
| geom | 描画に使用する幾何オブジェクト | GeomPolygon3D |
# データ作成:店舗と曜日の組み合わせ
set.seed(1)
visits <- data.frame(
store = sample(c("Sapporo", "Asahikawa", "Hakodate"), 600, replace = TRUE),
weekday = sample(c("Mon", "Wed", "Fri", "Sun"), 600, replace = TRUE))
# 離散×離散なので、組み合わせごとの度数がそのまま柱の高さになる
ggplot(visits, aes(store, weekday)) +
geom_bar_3d(fill = "steelblue") +
coord_3d()
# データ作成:相関のある2つの計測値
set.seed(2)
meas <- data.frame(sensor_a = rnorm(1500))
# sensor_aに比例する成分とノイズを足してsensor_bを作る
meas$sensor_b <- 0.6 * meas$sensor_a + rnorm(1500, 0, 0.8)
# 連続×連続なので2次元ビンに区切られ、3Dヒストグラムになる
ggplot(meas, aes(sensor_a, sensor_b)) +
geom_bar_3d(bins = c(18, 18), fill = "darkorange") +
coord_3d()
# 空のビンも高さ0の柱として表示する
ggplot(meas, aes(sensor_a, sensor_b)) +
geom_bar_3d(bins = c(12, 12), drop = FALSE) +
coord_3d()
# データ作成:3系統の測定値
set.seed(3)
lots <- data.frame(
lot = rep(c("L1", "L2", "L3"), each = 200),
value = c(rnorm(200, 5, 1), rnorm(200, 7, 1.5), rnorm(200, 6, 0.7)))
# 離散×連続の組み合わせでは、連続側だけがビンに使用される
ggplot(lots, aes(x = lot, y = value, fill = lot)) +
geom_bar_3d(bins = 20, width = c(0.6, 1)) +
coord_3d(scales = "fixed", ratio = c(1, 1, 0.1))
# 度数の代わりに密度をz軸に割り当てる
ggplot(lots, aes(x = lot, y = value, z = after_stat(density))) +
geom_bar_3d(bins = 20, width = c(0.6, 1)) +
coord_3d()実行例:詳細は上記コマンド例を確認してください。

回帰モデルの当てはめ結果を3D曲面として描く:geom_smooth_3dコマンド
散布した(x, y, z)データに平滑化モデルを当てはめ、その予測値を格子上で評価した3次元曲面がプロットできます。ggplot2のgeom_smooth()の3Dで、loess、lm、glm、gamに対応しています。信頼区間を追加の曲面として重ねたり、元のデータ点や残差線を一緒にプロット可能です。
| オプション | 意味 | 初期値 |
|---|---|---|
| mapping | aes()で作成した審美的属性のマッピング。x、y、zが必須で、fillは既定でafter_stat(fitted)に割り当てられる | NULL |
| data | このレイヤーで表示するデータ。x、y、z列を含む必要がある | NULL |
| stat | 使用する統計変換 | StatSmooth3D |
| position | 位置調整の方法。position_on_face()を指定すると結果を1つの平面に畳み込める | “identity” |
| … | レイヤー関数に渡すその他の引数。colour、fill、linewidth、annotate = annotate_3d(…)などを指定する | なし |
| method | 平滑化の方法。”loess”、”lm”、”glm”、”gam”が指定できる(gamにはmgcvパッケージが必要) | “loess” |
| formula | モデル式。NULLのときはlmとglmでz ~ x + y、gamでz ~ s(x) + s(y)が使われる | NULL |
| method.args | 当てはめ関数に渡す追加引数のリスト。loessならspan、glmならfamilyなど | list() |
| xlim | 予測用格子のx方向の範囲。NULLのときはデータの範囲そのままで外挿しない | NULL |
| ylim | 予測用格子のy方向の範囲。NULLのときはデータの範囲そのままで外挿しない | NULL |
| n | 予測用格子の解像度 | NULL |
| grid | 曲面を構成するタイルの形状 | NULL |
| direction | 格子の向き | NULL |
| trim | 格子の端の処理 | NULL |
| domain | 曲面を表示するx-y領域。”bbox”は説明変数の外接矩形全体、”chull”は凸包の内側だけを描く | c(“bbox”, “chull”) |
| se | 信頼区間の帯を表示するかどうか。TRUEにすると追加の曲面として描画される | FALSE |
| level | 信頼区間の水準 | 0.95 |
| se_fill | 信頼区間の帯の塗り色。NULLのとき本体の曲面のfillを継承する | NULL |
| se_colour | 信頼区間の帯の輪郭線の色。NULLのとき本体の曲面のcolorを継承する | NULL |
| se_color | se_colourの別綴り | NULL |
| se_alpha | 信頼区間の帯の透過度 | 0.5 |
| se_linewidth | 信頼区間の帯の輪郭線の太さ。NULLのとき本体の曲面のlinewidthを継承する | NULL |
| points | 元のデータ点を曲面上に重ねて描くかどうか。点は曲面と一緒に奥行きソートされる | FALSE |
| point_colour | データ点の色 | “black” |
| point_color | point_colourの別綴り | NULL |
| point_fill | データ点の塗り色。shapeが21から25のときのみ有効 | NA |
| point_size | データ点の大きさ | 1.5 |
| point_shape | データ点の形状番号 | 19 |
| point_alpha | データ点の透過度 | 1 |
| point_stroke | データ点の輪郭線の太さ | 0.5 |
| residuals | データ点と曲面を結ぶ残差線を描くかどうか。se = TRUEと併用すると正しく描画されない場合がある | FALSE |
| residual_colour | 残差線の色 | “black” |
| residual_color | residual_colourの別綴り | NULL |
| residual_linewidth | 残差線の太さ | 0.5 |
| residual_linetype | 残差線の線種 | 1 |
| residual_alpha | 残差線の透過度 | 1 |
| light | light()で作成した照明設定オブジェクト。”none”で無効、NULLで座標系の設定を継承する | NULL |
| cull_backfaces | 視点と反対を向いたポリゴンを描画から除くかどうか | FALSE |
| sort_method | 奥行きソートのアルゴリズム | NULL |
| force_convex | 凸包に含まれない頂点をポリゴンから除去するかどうか | TRUE |
| scale_depth | 手前の線を太く、奥の線を細くするよう線幅を調整するかどうか | TRUE |
| na.rm | FALSEのとき欠損値を取り除く | FALSE |
| show.legend | このレイヤーを凡例に含めるかどうか | NA |
| inherit.aes | FALSEのとき既定の審美的属性を上書きする | TRUE |
| geom | 描画に使用する幾何オブジェクト | GeomPolygon3D |
### データの作成:温度と湿度から収量が決まる栽培試験#####
set.seed(123)
crop <- data.frame(
temp = runif(120, 10, 30),
humid = runif(120, 30, 90))
# 最適点から離れるほど収量が落ちる二次の関係にノイズを加える
crop$yield <- 50 - 0.08 * (crop$temp - 22)^2 -
0.01 * (crop$humid - 60)^2 + rnorm(120, 0, 2)
########
# 曲面を重ねる土台となるプロットを作成
p_smooth <- ggplot(crop, aes(temp, humid, yield)) +
coord_3d() +
scale_fill_viridis_c()
# 既定のloessによる平滑化曲面を描く
p_smooth + geom_smooth_3d()
# 元のデータ点と、点から曲面へ下ろした残差線を重ねる
p_smooth + geom_smooth_3d(points = TRUE, residuals = TRUE,
point_color = "red", alpha = 0.8)
# 二次の項を含むモデル式を明示して線形モデルを当てはめる
p_smooth + geom_smooth_3d(method = "lm", n = 12,
formula = z ~ poly(x, 2) + poly(y, 2))
# loessの平滑化の強さをspanで調整し、照明効果を加える
p_smooth + geom_smooth_3d(method = "loess",
method.args = list(span = 0.5),
fill = "steelblue", color = "white", n = 20,
light = light(direction = c(0, -1, 1)))
# 95%信頼区間を上下の曲面として重ねて描く
p_smooth + geom_smooth_3d(aes(fill = after_stat(level)),
method = "lm", color = "black", se = TRUE,
level = 0.95, se_alpha = 0.6, n = 10) +
scale_fill_manual(values = c("tomato", "gray40", "steelblue"))
# 標準誤差そのものを塗り分けに使い、予測の不確実さを可視化する
p_smooth + geom_smooth_3d(aes(fill = after_stat(se)), n = 15) +
scale_fill_viridis_c(option = "magma")
# データが存在しない隅への外挿を避けるため、凸包の内側だけを描く
p_smooth + geom_smooth_3d(method = "lm", domain = "chull", n = 15)
# データ範囲の外側まで格子を広げて、明示的に外挿させる
p_smooth + geom_smooth_3d(method = "lm", n = 12,
xlim = c(5, 35), ylim = c(20, 100))・95%信頼区間を上下の曲面として重ねて描く:他の実行例は省略

z軸の目盛りやラベル、範囲、変換を指定する:scale_z_continuousコマンド
scale_x_continuous()やscale_y_continuous()と同じ感覚で、目盛りの位置、ラベルの文字列、軸の範囲、対数や逆順といった変換を指定できます。
| オプション | 意味 | 初期値 |
|---|---|---|
| name | スケールの名前で、軸タイトルとして使われる。NULLでタイトルを省略できる | waiver() |
| breaks | 主目盛りの位置。NULL、waiver()、数値ベクトル、または範囲を受け取って位置を返す関数を指定する | waiver() |
| minor_breaks | 補助目盛りの位置。指定方法はbreaksと同じ | waiver() |
| n.breaks | 主目盛りのおおよその個数。読みやすいラベルにするため実際の個数は多少変わる | NULL |
| labels | 目盛りラベル。NULL、waiver()、breaksと同じ長さの文字ベクトル、または関数を指定する | waiver() |
| limits | スケールの下限と上限を表す長さ2の数値ベクトル。NAで既存の最小値または最大値を使う | NULL |
| expand | データと軸の間に余白を確保するための拡張量 | waiver() |
| oob | 範囲外の値の扱い。scales::censorでNAに置換、scales::squishで範囲内に押し込む | scales::censor |
| na.value | 欠損値を置き換える値 | NA_real_ |
| transform | 変換の名前または変換オブジェクト。”log10″、”sqrt”、”reverse”などが使える | “identity” |
| guide | ガイドの作成方法。z軸のガイドは未対応のため既定は”none” | “none” |
| … | continuous_scale()に渡すその他の引数 | なし |
### データの作成:製品の価格・重量・連続使用時間#####
set.seed(7)
product <- data.frame(
price = round(runif(60, 1000, 5000)),
weight = round(runif(60, 100, 900)),
hours = round(runif(60, 5, 40)))
########
# z軸の目盛り位置とラベル、下限を明示して描画する
ggplot(product, aes(price, weight, hours)) +
geom_point_3d(color = "steelblue") +
scale_z_continuous(
name = "Battery life",
breaks = c(10, 20, 30, 40),
labels = c("10h", "20h", "30h", "40h"),
limits = c(0, NA)) +
coord_3d()
# z軸を逆順にして、値が小さいほど上に来るようにする
ggplot(product, aes(price, weight, hours)) +
geom_point_3d(color = "firebrick") +
scale_z_continuous(transform = "reverse") +
coord_3d()
# 目盛りの個数だけを指定して、位置は自動で決めさせる
ggplot(product, aes(price, weight, hours)) +
geom_point_3d() +
scale_z_continuous(n.breaks = 8) +
coord_3d()・z軸を逆順にして、値が小さいほど上に来るようにする:他の実行例は省略

2次元のプロットを簡単に3D表現にする:aesコマンド
ggcubeのaes()は、aes(x, y, z)と3つ並べて書くだけでz軸を割り当てることができ、2次元のプロットを簡単に3D表現にすることが可能です。
| オプション | 意味 | 初期値 |
|---|---|---|
| x | x軸に割り当てる変数(必須) | なし |
| y | y軸に割り当てる変数(必須) | なし |
| z | z軸に割り当てる変数(省略可) | なし |
| … | color、sizeなどその他の審美的属性のマッピング | なし |
実行結果のプロットは省略します。便利なコマンドです。
### データの作成:製品の価格・重量・連続使用時間#####
set.seed(7)
product <- data.frame(
price = round(runif(60, 1000, 5000)),
weight = round(runif(60, 100, 900)),
hours = round(runif(60, 5, 40)))
########
# 2つだけ引数を渡した場合は、通常のggplot2と同じ2次元プロットになる
ggplot(product, aes(price, weight)) +
geom_point()
# 3つ目の引数が自動的にz軸へ割り当てられる
ggplot(product, aes(price, weight, hours)) +
geom_point() +
coord_3d()
# z = を明示した書き方でも結果は同じ
ggplot(product, aes(x = price, y = weight, z = hours)) +
geom_point() +
coord_3d()回転させたコマ送りをGIFや動画として書き出す:animate_3dコマンド
coord_3d()を使ったプロットの回転をフレーム間で補間しながら描画し、アニメーションとして出力します。pitch、roll、yawに長さ2以上の数値ベクトルを渡すと、その値をキーフレームとして線形補間されます。既定のGIF出力にはgifskiパッケージ、動画出力にはavパッケージが別途必要です。
なお、RStudioを使用するとViewerペインにプロットが表示されます。そのまま、Show in new windowボタンをクリックすると、ブラウザでプロットが表示されます。ブラウザからデスクトップにドラッグアンドドロップするとアニメーションgifの保存が可能です。保存はanim_save_3dコマンドでも可能です。
| オプション | 意味 | 初期値 |
|---|---|---|
| plot | coord_3d()を使ったggplotオブジェクト | なし |
| pitch | y軸まわりの回転の指定。NULLで元のcoord_3d()の値を保持、単一の数値で全フレーム固定、長さ2以上の数値ベクトルでキーフレーム間を線形補間する | NULL |
| roll | x軸まわりの回転の指定。指定方法はpitchと同じ | NULL |
| yaw | z軸まわりの回転の指定。指定方法はpitchと同じ | NULL |
| nframes | 総フレーム数。nframes、fps、durationのうち2つを指定すると残り1つが計算される | NULL |
| fps | 1秒あたりのフレーム数。既定はnframes = 100、fps = 10 | NULL |
| duration | アニメーションの長さ(秒)。duration = nframes / fpsの関係になる | NULL |
| width | 出力するアニメーションの幅(ピクセル) | 480 |
| height | 出力するアニメーションの高さ(ピクセル) | 480 |
| res | 各フレームの解像度(ppi)。文字や線などポイント基準の要素の大きさに影響する | 96 |
| renderer | フレーム画像を1つのファイルにまとめる関数。gifski_renderer_3d()、av_renderer_3d()、file_renderer_3d()が用意されている | gifski_renderer_3d() |
| start_pause | アニメーション開始時に静止させるフレーム数 | 0 |
| end_pause | アニメーション終了時に静止させるフレーム数 | 0 |
| rewind | TRUEにすると再生後に逆再生し、途切れないループになる | FALSE |
| cores | フレームの並列描画に使うCPUコア数。1より大きい値でparallel::parLapply()が使われるが、進捗表示は無効になる | 1 |
| device | フレーム描画に使うグラフィックデバイス。”ragg_png”を使う場合はraggパッケージが必要 | “png” |
| progress | 進捗バーを表示するかどうか。cores > 1のときは無視される | interactive() |
# GIF出力にはgifskiパッケージが必要
install.packages("gifski")
# アニメーションさせる地形プロットを作成
# anchor = "camera"を指定すると、回転しても光源が固定される
p_anim <- ggplot(terrain, aes(x, y, z)) +
geom_surface_3d(fill = "steelblue", color = "steelblue",
linewidth = 0.2) +
coord_3d(light = light(mode = "hsl", anchor = "camera",
direction = c(1, 1, 0))) +
theme_void()
# z軸まわりに1周させる(実行時間を抑えるためフレーム数は少なめ)
animate_3d(p_anim, yaw = c(-30, 330), nframes = 24, fps = 12)
# yawで2周させながら、途中でrollを変化させる
animate_3d(p_anim, yaw = c(0, 720), roll = c(-90, -30, -90),
nframes = 36, fps = 15)
# 開始と終了で静止させ、逆再生を付けてループさせる
animate_3d(p_anim, yaw = c(-30, 90), nframes = 24,
start_pause = 5, end_pause = 5, rewind = TRUE)
# 作成したアニメーションをGIFとして保存
anim <- animate_3d(p_anim, yaw = c(0, 360), nframes = 24)
anim_save_3d(anim, file.path(tempdir(), "terrain_rotation.gif"))
<おすすめのRに関する書籍です>
この記事が誰かの役に立ちますように。