Search code examples
rr-markdownknitrrglr-car

knitr bookdown::gitbook and webgl: rotation does not work properly


I have the following Rmd file:

---
output: bookdown::gitbook
---

```{r include=FALSE}
rgl::setupKnitr()
```

```{r testing1,webgl=TRUE}
with(attitude,
  car::scatter3d(x = rating, z = complaints, y = learning)
)
```

```{r testing2,webgl=TRUE}
with(attitude,
  car::scatter3d(x = rating, z = complaints, y = learning)
)
```

When I knit this file, it produces and HTML file containing two, identical 3D interactive scatterplots. Both scatterplots look like they should, but the second scatterplot does not rotate properly. It will not rotate horizontally in depth correctly (eg, around the vertical axis).

In case it helps, you can find the HTML output of the knit here: https://www.dropbox.com/s/v3usmtes7n54t6q/Untitled.html.zip?dl=0

I have done all the following, none of which have fixed the problem:

  1. Updated all packages with update.packages().
  2. Installed the development version of bookdown.
  3. Installed the development version of knitr.
  4. Tried the solution here (didn't work): interactive 3D plots in markdown file - not working anymore?

I have noted the following:

  • If I change the output to html_document I do not have the problem (I'm debugging the problem in a bookdown::gitbook though, so that knowledge does not directly help me).
  • In the Firefox (77.0.1, 64-bit) javascript error console there is an error: TypeError: li[0] is undefined / plugin-bookdown.js:152:43 (which appears to have something to do with the table of contents and scrolling?)

Here is the output of sessionInfo():

> sessionInfo()
R version 4.0.0 (2020-04-24)
Platform: x86_64-apple-darwin17.0 (64-bit)
Running under: macOS Catalina 10.15.5

Matrix products: default
BLAS:   /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/4.0/Resources/lib/libRlapack.dylib

locale:
[1] en_GB.UTF-8/en_GB.UTF-8/en_GB.UTF-8/C/en_GB.UTF-8/en_GB.UTF-8

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

loaded via a namespace (and not attached):
 [1] bookdown_0.19.4  fansi_0.4.1      digest_0.6.25    crayon_1.3.4    
 [5] assertthat_0.2.1 evaluate_0.14    rlang_0.4.6      cli_2.0.2       
 [9] rstudioapi_0.11  rmarkdown_2.3    tools_4.0.0      glue_1.4.1      
[13] xfun_0.14        yaml_2.2.1       rsconnect_0.8.16 compiler_4.0.0  
[17] htmltools_0.5.0  knitr_1.28.7  

In addition, here are the versions of some other relevant packages:

> installed.packages()[c("rgl","mgcv","car"),"Version"]
       rgl       mgcv        car 
"0.100.54"   "1.8-31"    "3.0-8" 

Edit to add more detail

I have the same problem while using rgl::persp3d, so it isn't specific to car::scatter3d. The HTML from the Rmd file below uses only rgl but exhibits the same behavior.

---
output: bookdown::gitbook
---

```{r include=FALSE}
rgl::setupKnitr()

x <- seq(-10, 10, length = 30)
y <- x
f <- function(x, y) { r <- sqrt(x^2 + y^2); 10 * sin(r)/r }
z <- outer(x, y, f)
z[is.na(z)] <- 1
```

```{r testing1,webgl=TRUE}
rgl::persp3d(x, y, z, aspect = c(1, 1, 0.5), col = "lightblue",
        xlab = "X", ylab = "Y", zlab = "Sinc( r )", 
        polygon_offset = 1)
```

```{r testing2,webgl=TRUE}
rgl::persp3d(x, y, z, aspect = c(1, 1, 0.5), col = "lightblue",
        xlab = "X", ylab = "Y", zlab = "Sinc( r )", 
        polygon_offset = 1)
```

Solution

  • This turned out to be a bug in rgl, that was using an obsolete method to compute the location of mouse clicks relative to objects in scenes. It worked in an html_document, but not with bookdown::gitbook.

    The development version (0.102.6) of rgl has fixed this, but it contains some really major changes, and a few other things are still broken by them: in particular using the webgl=TRUE chunk option. If you want to use the devel version, you should use explicit calls to rglwidget() in each chunk, or if you want to try out the new stuff, use rgl::setupKnitr(autoprint = TRUE) and just treat rgl graphics like base graphics, controlled by chunk options fig.keep etc.

    Edited to add: version 0.102.7 fixes the known webgl=TRUE issue.