Including a Interactive 3D Figure with Knitr

including a interactive 3D figure with knitr

I added a new hook hook_webgl() in knitr, which was incorporated into rgl later. Here is an example:

```{r setup}
library(knitr)
library(rgl)
knit_hooks$set(webgl = hook_webgl)
```

```{r testgl, webgl=TRUE}
x <- sort(rnorm(1000))
y <- rnorm(1000)
z <- rnorm(1000) + atan2(x,y)
plot3d(x, y, z, col=rainbow(1000))
```

Including a 3D interactive figure in html and static in word/pdf using knitr and rgl

You could use the following setup to switch according to the output format

```{r, echo=FALSE}
out_type <- knitr::opts_knit$get("rmarkdown.pandoc.to")
keep <- if(out_type == "html") 'none' else 'last'
```

```{r chunk, echo=FALSE, fig.keep=keep}
plot(cars)
if(out_type == "html")
cat("there goes fancy js code")
```

How to include multiple plot3d in markdown (knitr) under a loop

One way you can do it is to use mfrow3d() to put multiple "subscenes" in a single "scene", then use the rglwidget() command to show the scene in your html. See more information here. Below is a heavily modified version of the script from Yihui's answer:

---
output: html_document
---

You will need to install the rglwidget library if you have not already.
```{r setup}
library(knitr)
library(rgl)
library(rglwidget)
```

Using mfrow3d() I create a scene with 5 subscenes,
so each of the 5 plots will appear in a single scene.
Each will still be independently interactive (can zoom in on one at a time, e.g.).

```{r testgl}
x <- sort(rnorm(1000))
y <- rnorm(1000)
z <- rnorm(1000) + atan2(x,y)

mfrow3d(nr = 5, nc = 1)
cols <- c("red", "orange", "green", "blue", "purple")
for(i in 1:5){
plot3d(x, y, z, col = cols[i])
}
rglwidget(height = 4000, width = 1000)
```

RMarkdown: How to embed an 3D plot?

What you did should work, but it's not the best way to embed rgl graphics in a document.

The simplest way is to make a call to rglwidget() where you want the current plot inserted. You can also use options(rgl.useNULL=TRUE) to suppress the separate window that rgl creates when it plots. For example,

---
title: Embed 3D plots with rgl
output: html_document
---

No need for a hook with `rgl` version >= 0.96.0, just call `rglwidget()`.

```{r, setup}
options(rgl.useNULL = TRUE) # Suppress the separate window.
library(rgl)
```

See it work for this 3D plot without the hook:

```{r}
x <- sort(rnorm(1000))
y <- rnorm(1000)
z <- rnorm(1000) + atan2(x,y)
plot3d(x, y, z, col = rainbow(1000))
rglwidget()
```

Version 0.102.21 or newer of rgl makes it even simpler: rgl plots can be made to appear under almost the same rules as base graphics plots, with just a call to rgl::setupKnitr(autoprint = TRUE) at the beginning.

I said what you tried should work, and it does for me. Why not for you? It's hard to guess what went wrong, but the most likely thing is probably that your web browser doesn't have WebGL enabled, or you're using some old version of R or rgl that has a bug in it. One simple workaround for a bad browser is to switch to a static plot; you could do that with your code by changing hook = hook_webgl to hook = hook_rgl.

Include rgl interactive plot in .Rnw (pdf output)

It's possible, but just barely. You need to install Asymptote, and use rgl::writeASY() to write a program for it. Then include that program in your document, run LaTeX, then Asymptote, then LaTeX again.

There are examples of including Asymptote in LaTeX here: http://asymptote.sourceforge.net/doc/LaTeX-usage.html#LaTeX-usage.

The results are kind of disappointing.

My advice would be to abandon PDF. HTML5 is a much better target for output; rgl does quite a good job (using rglwidget()) producing output for web pages. It's really unlikely that any effort will be put into improving PDF output, whereas fixing the remaining gaps in HTML support are a priority.

Rottation of R 3d plots not working properly with knitr and webgl

This is a bug in knitr, and has been fixed in the development version. The reason for it is that rgl includes <script src="CanvasMatrix.js" type="text/javascript"></script> for every plot, even when there are multiple plots on the same page. I have removed this line on knitr's side, so that CanvasMatrix.js is only loaded once. The knitr example you mentioned works now.

knitr: How to set a figure path in knit2html without using setwd()?

Take a look at this page on chunk options. In particular, you have two options

  1. Use fig.path to set the plot directory relative to your working directory (OR)
  2. Use base.dir to set an absolute directory in which to save plots.

I think (2) might be a better solution in your context. Do not use setwd() in a knitr document since it is not good practice for keeping documents reproducible.



Related Topics



Leave a reply



Submit