多次元データや地形情報を可視化する際、2次元プロットだと情報の把握が困難な場合があります。 このような時は3次元グラフィックスを用いると効果的に可視化できます。 今回はRで簡単に3次元グラフィックスを作成する方法を紹介します。
Rで3次元プロットを作成するにはpersp()
関数、scatterplot3d
パッケージ、lattice
パッケージなどを利用できます(図1)。
> # scatterplot3d による3次元プロット
> library(scatterplot3d)
> scatterplot3d(iris[, 1:3], pch = as.numeric(iris$Species))
>
> # latticeを使った3次元プロット
> library(lattice)
> cloud(Petal.Length ~ Sepal.Length * Sepal.Width, data = iris, groups = Species)
3次元プロットの場合、色々な視点からプロットを眺めることで情報を効率的に把握できます。 これらの関数ではプロット作成時にパラメータによって視点を設定することは可能ですが、 見ている人が自由に視点を操作することはできません(「静的」とはインタラクティブに視点を操作できない、という意味です)。
rgl
パッケージrgl
パッケージでは、OpenGLベースの自由度の高い3次元グラフィックスの作成、及び作成した3次元プロットに対する視点移動やズームイン・ズームアウトといったインタラクティブな操作を行うことができます。
OpenGLは3Dコンピュータグラフィックスを扱うための仕様ですが、rgl
パッケージで3次元プロットを作成するだけならOpenGLの知識は不要です。
データを探索的に把握したいときなどは、静的な3次元プロットよりもrgl
パッケージの方が便利です。
まずはデモを動かして、どのような3次元プロットを作成できるのか見てみましょう。
> install.packages("rgl") # 必要なら
> library(rgl)
> demo(rgl)
ウィンドウが開いて3次元プロットが表示されます(図2)。ウィンドウ上をマウスでドラッグすると視点の移動が、ホイールスクロールによりズームイン・ズームアウトが可能です。
rgl
パッケージでは目的に応じて3次元プロットを簡単に作成するための関数が提供されています。
plot3d()
により3次元散布図を作成できます(図3)。ベースグラフィックスのplot
と同じように色や点のサイズなどを指定することもできます。
> plot3d(mtcars[c("disp", "drat", "mpg")], col = rainbow(3)[factor(mtcars$cyl)])
planes3d()
を使うとlm()
による線形回帰で得られる回帰平面を追加できます。
> fit <- lm(mpg ~ disp + drat, mtcars)
> coefs <- coef(fit)
> planes3d(coefs[2], coefs[3], -1, coefs[1], col="blue", alpha=0.5)
ellipse3d()
を使うと回帰係数の同時信頼区間を表示できます。
> plot3d(ellipse3d(fit, level = 0.95), aspect=TRUE)
plot3d()
ではtype
引数でプロットの種類を指定できます。p
は点(デフォルト)、s
は球、l
は線、h
は垂直線を描画します(図4)。
> # ラインプロット
> T <- seq(0, 10*2*pi, len = 500)
> F <- seq(0.5, 2, len = 500)
> plot3d(cos(T)*F, sin(T)*F, seq(0, 1, len = 500), type = "l")
>
> # 球+垂直線プロット
> x <- runif(50); y <- runif(50); z <- runif(50)
> plot3d(x, y, z, type = "s")
> plot3d(x, y, z, type = "h", add = TRUE)
persp3d()
により曲面を可視化できます。
高さのある地形データや多次元確率変数のような2変数の関数を把握するのに便利です。
次の例では2次元正規分布の確率密度を可視化しています(図4)。
> x <- y <- seq(-3,3,length.out=100)
> xy <- as.matrix(expand.grid(x, y))
> z <- mvtnorm::dmvnorm(xy)
> persp3d(x, y, z, col = "gray")
rgl
パッケージでは視点を連続して移動することでアニメーション風にプロットを表示できます。
play3d()
により表示、movie3d()
により動画の保存が可能です。
これらの関数とspin3d()
を組み合わせることで、ぐるぐるまわるアニメーションを簡単に作成できます。アニメーションを停止するにはエスケープキーを押して下さい。
> plot3d(mtcars[c("disp", "drat", "mpg")])
> play3d(spin3d(c(0, 0, 1), 15))
rgl
パッケージでは3次元プロットの注釈やタイトル、軸などを設定するための関数も提供されています。
以下に重要な関数を抜粋します。詳細は?関数名
としてヘルプファイルを参照して下さい。
関数名 | 説明 |
---|---|
par3d |
様々なパラメータの指定 |
aspect3d |
アスペクト比の指定 |
axes3d |
座標軸に関する一括設定 |
axis3d |
座標軸の個別設定 |
open3d |
描画デバイスを開く |
close3d |
描画デバイスを閉じる |
decorate3d |
座標軸やタイトルなどの一括指定 |
text3d |
テキスト注釈の追加 |
mtext3d |
テキスト注釈の追加 |
title3d |
タイトルの追加 |
bg3d |
背景色の指定 |
grid3d |
グリッド線の追加 |
view3d |
視点の移動 |
これまでの例では、R上で3次元プロットを表示していましたが、レポートなどを作成するために3次元プロットを画像で保存できます。
rgl.postscript()
ではPDF、SVGなどのベクタフォーマットの画像に、
rgl.snapshot()
ではPNG画像に保存できます。
なお、rgl
で続けてプロットを作成すると、たくさんのデバイスウィンドウが開きますが、
これらの画像出力関数ではアクティブな描画デバイスのプロットが保存されます(フォーカスのあるウィンドウではありません)。
rgl.dev.list()
でデバイスのリストの取得、rgl.set()
でアクティブなデバイスの変更が可能です。
WebGLとはウェブブラウザ上でOpenGLグラフィックスを扱うための仕組みです。
rgl
パッケージではwriteWebGL()
関数によって3次元プロットをWebGLとして出力することができます。
HTMLファイルが作成されるので、これをウェブブラウザで開くことでインタラクティブな3次元プロットをブラウザ上で利用できるようになります。
但しWebGLのブラウザでの制約により、データ点が多すぎる場合(特にサーフェスプロットは点の数が膨大になるのでWebGLでは表示できない場合もあります)や視点移動のアニメーションなどの複雑な処理はサポートされていないことがあります。
> plot3d(mtcars[c("disp", "drat", "mpg")])
> writeWebGL()
> browseURL("webGL/index.html")
以上の操作によりwebGL
フォルダの中にindex.html
というファイルが作成されます。ブラウザ上でマウスを使って3次元プロットを操作してみてください。
なお、ブラウザによってはWebGLを再生するために設定が必要な場合があります。また出来るだけ最新のブラウザを使って下さい。
作成したHTMLファイルを別の環境で利用する場合は、webGL
フォルダ内のCanvasMatrix.js
、snapshot.png
というファイルもあわせて配布します。
knitr
パッケージでのWebGLの利用knitr
パッケージやrmarkdown
パッケージを使うとウェブレポートを作成することができます。
この中でインタラクティブに操作できる3次元プロットを表示することも可能です。
knitr
やrmarkdonw
については本誌2013年10月号、2014年11月号、『シリーズUseful R ドキュメント・プレゼンテーション生成』(共立出版)などを参考にして下さい。
以下にRマークダウンファイルの例を示します(k.Rmd)。
```{r include=FALSE}
library(rgl)
library(knitr)
knit_hooks$set(webgl = hook_webgl)
```
```{r results='asis', echo=FALSE}
writeLines(c('<script type="text/javascript">',
readLines(system.file('WebGL', 'CanvasMatrix.js', package = 'rgl')), '</script>'))
```
# mtcarsの3次元プロット
```{r webgl=TRUE, echo=FALSE, fig.width=3, fig.height=3}
plot3d(mtcars[c("disp", "drat", "mpg")])
```
排気量、アクセル比、燃費の関係を可視化しました。
今回紹介した3次元プロット作成関数以外にも、照光処理、行列による座標変換、マテリアル設定など、rgl
パッケージによりOpenGLの豊富な機能を使った高度な3Dグラフィックスを作成することができます。
今後はビッグデータ化により、扱うデータがより高次元で複雑なものになることが予想されます。3次元可視化を習得して、是非このような複雑なデータに対して効果的な可視化を実践して下さい。