Rotierbare 3D-Objekte mit webGL
Das rgl-package bietet in R eine Möglichkeit, dreidimensionale Daten interaktiv darzustellen. Mit der Maus kann man das 3D-Objekt rotieren und mit dem Mausrad kann man es näher heran holen (vergrößern) und verkleinern. Für die Darstellung benutzt rgl OpenGL. Um die 3D-Inhalte in intaktiver Form auch in Webseiten einbinden zu können, kann OpenGL nach WebGL umgewandelt werden. WebGL kann von allen aktuellen Browsern (auch den mobilen) dargestellt werden1. Wenn rgl-Befehle wie plot3d()
in knitr-Dokumente eingebettet werden, wird beim compilieren automatisch ein WebGL-Objekt generiert und in die html-Seite eingebettet. Vorraussetzung ist, dass man die Chunk-Option webgl=TRUE
setzt. Bei Bedarf kann dieses in die html-Seite eingebettet werden. Dazu muss folgendes im Head der markdown-Datei definiert sein:
output:
html_document:
self_contained: yes
Ausserdem müssen im ersten Chunk (z.B. im “Setup”-Chunk) folgende Befehle ausgeführt werden:
library(rgl)
knit_hooks$set(webgl = hook_webgl)
options(rgl.useNULL = TRUE)
Der erste Befehl lädt rgl, der zweite ermöglicht das setzen von webgl=TRUE
in den Chunk-Einstellungen. Der letzte Befehl sorgt dafür, dass kein rgl Fenster beim Generieren der Seite geöffnet wird, sondern die Grafik direkt in die html-Seite eingebunden wird.
Hier einige Beispiele:
z <- 2 * volcano # Exaggerate the relief
x <- 10 * (1:nrow(volcano)) # 10 meter spacing (S to N)
y <- 10 * (1:ncol(volcano)) # 10 meter spacing (E to W)
n_colors <- diff(range(volcano))
colors <- terrain.colors(n_colors)
persp3d(x, y, z, col = colors[volcano - min(volcano)], aspect = "iso",
axes = F, box = F, xlab = "", ylab = "", zlab = "")
You must enable Javascript to view this page properly.
open3d()
shade3d(translate3d(tetrahedron3d(col = "red"), 0, 0, 0))
You must enable Javascript to view this page properly.
x <- runif(1000)
y <- runif(1000)
z <- x + rnorm(1000, mean = 0, sd = 0.05)
plot3d(x, y, z, col = rainbow(1000))
par3d(FOV = 0.1)
mat <- matrix(c(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0.5), nrow = 4)
par3d(userMatrix = mat)
You must enable Javascript to view this page properly.
x <- rnorm(1000)
y <- rnorm(1000)
z <- x + rnorm(1000, mean = 0, sd = 0.05)
plot3d(x, y, z, col = rainbow(1000))
par3d(FOV = 0.1)
mat <- matrix(c(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1), nrow = 4)
par3d(userMatrix = mat)
You must enable Javascript to view this page properly.
x <- rnorm(1000)
y <- rnorm(1000)
z <- rnorm(1000)
cols <- z + rnorm(1000, mean = 0, sd = 0.05)
cols <- (cols - min(cols))/diff(range(cols)) * (1000 - 1) + 1
plot3d(x, y, z, col = rainbow(1000)[cols], box = F, axes = F, xlab = "",
ylab = "", zlab = "")
par3d(FOV = 0.1)
par3d(userMatrix = mat, zoom = 0.3)
You must enable Javascript to view this page properly.
Das letzte Beispiel zeigt, wie man mit rglwidget auch animierte 3D-Darstellungen per WebGL einbinden kann. Dieses Beispiel ist dem htmlwidgets showcase entnommen.
library(rgl)
library(rglwidget)
library(htmltools)
theta <- seq(0, 6 * pi, len = 100)
xyz <- cbind(sin(theta), cos(theta), theta)
lineid <- plot3d(xyz, type = "l", alpha = 1:0, lwd = 5, col = "blue")["data"]
browsable(tagList(rglwidget(elementId = "example", width = 500, height = 400,
controllers = "player"), playwidget("example", ageControl(births = theta,
ages = c(0, 0, 1), objids = lineid, alpha = c(0, 1, 0)), start = 1,
stop = 6 * pi, step = 0.1, rate = 6, elementId = "player")))