{gganimate} rendering fails with svg figure output
Closed this issue · 3 comments
Bug description
When rendering to html with fig-output: svg
, plots which make use of {gganimate}
won't render. Errors implicate device()
, as below.
Error in `device()`:
! unused arguments (units = "in", res = 96)
A workaround is to set dev: png
in the relevant chunk options. This fails, however, if a plot is saved and then rendered with animate()
.
Steps to reproduce
Apologies for the slightly long example. The document will render fine if fig-format: svg
is removed from the yaml header.
---
title: "gganimate example"
execute:
fig-format: svg
echo: false
---
```{r}
library(gganimate)
```
Should work (using `#| dev: png`):
```{r}
#| dev: png
ggplot(mtcars, aes(factor(cyl), mpg)) +
geom_boxplot() +
transition_states(gear)
```
Will fail (no device override):
```{r}
ggplot(mtcars, aes(factor(cyl), mpg)) +
geom_boxplot() +
transition_states(gear)
```
Will fail (device override but uses `animate()`)
```{r}
#| dev: png
p <- ggplot(mtcars, aes(factor(cyl), mpg)) +
geom_boxplot() +
transition_states(gear)
animate(p)
```
Expected behavior
The animated plots should be created without needing to change device settings, or restrictions on devices should be clearly documented. It should be possible to render an animated plot using animate()
in a document which has a global setting of fig-format: svg
(at the moment that does not appear to be the case).
Actual behavior
An error is raised when attempting to render an animation, unless dev: png
is in the chunk options.
However even when dev: png
is in the chunk options, if animate()
is called, an error is raised.
Your environment
- IDE: RStudio 2023.06.2+561
- OS: Arch Linux (kernel 6.4.12-zen1-1-zen)
Quarto check output
[✓] Checking versions of quarto binary dependencies...
Pandoc version 3.1.1: OK
Dart Sass version 1.55.0: OK
[✓] Checking versions of quarto dependencies......OK
[✓] Checking Quarto installation......OK
Version: 1.3.450
Path: /opt/quarto/bin
[✓] Checking basic markdown render....OK
[✓] Checking Python 3 installation....OK
Version: 3.11.5
Path: /usr/bin/python3
Jupyter: (None)
Jupyter is not available in this Python installation.
Install with python3 -m pip install jupyter
[✓] Checking R installation...........OK
Version: 4.3.1
Path: /usr/lib64/R
LibPaths:
- /home/martinc/lib/R
- /usr/lib/R/library
knitr: 1.43
rmarkdown: 2.24
[✓] Checking Knitr engine render......OK
I believe this is not specific to Quarto but is an issue with knitr maybe. Anyhow, this is also happening with rmarkdown
---
title: "Label shouldn't be named"
output:
html_document:
dev: svg
---
```{r}
library(gganimate)
```
Should work (using `#| dev: png`):
```{r}
#| dev: png
ggplot(mtcars, aes(factor(cyl), mpg)) +
geom_boxplot() +
transition_states(gear)
```
Will fail (no device override):
```{r}
ggplot(mtcars, aes(factor(cyl), mpg)) +
geom_boxplot() +
transition_states(gear)
```
Will fail (device override but uses `animate()`)
```{r}
#| dev: png
p <- ggplot(mtcars, aes(factor(cyl), mpg)) +
geom_boxplot() +
transition_states(gear)
animate(p)
```
So I'll look at it in this context.
Ok so this is an issue with svg
device in ggganimate when use in knitr context
First, this is the traceback from the rendering.
Quitting from lines 24-27 [unnamed-chunk-3] (test.Rmd)
Error in `device()`:
! unused arguments (units = "in", res = 192)
Backtrace:
1. rmarkdown::render(...)
2. knitr::knit(knit_input, knit_output, envir = envir, quiet = quiet)
3. knitr:::process_file(text, output)
7. knitr:::process_group.block(group)
8. knitr:::call_block(x)
...
19. knitr (local) value_fun(ev$value, ev$visible)
20. knitr (local) fun(x, options = options)
23. gganimate::knit_print.gganim(x, ...)
26. gganimate:::animate.gganim(...)
28. gganimate (local) `<fn>`(...)
We see error comes from gganimate itself. Especially here:
https://github.com/thomasp85/gganimate/blob/7cd46dc2bc8cf18c1c81f6ef7fc4d00a1d57a385/R/animate.R#L305-L306
Basically some options are passed to svg()
device function and they are not argument of grDevices::svg()
- gganimate does define a
knit_print
method : https://github.com/thomasp85/gganimate/blob/7cd46dc2bc8cf18c1c81f6ef7fc4d00a1d57a385/R/gganim.R#L36C1-L37 - It will defined some option among which
units
andres
when no width or height; Bothunits
andres
are in your error message https://github.com/thomasp85/gganimate/blob/7cd46dc2bc8cf18c1c81f6ef7fc4d00a1d57a385/R/gganim.R#L46-L54 - Those options will be passed up to the device used selected in
draw_frames
https://github.com/thomasp85/gganimate/blob/7cd46dc2bc8cf18c1c81f6ef7fc4d00a1d57a385/R/animate.R#L285-L296
So when fig-format: svg
is defined in Quarto, it will trigger usage of svg
device in gganimate but it seems to be broken as the package itself defines some options unknown to svg()
function.
Regarding the last chunk, this is also gganimate issue . Traceback is
Quitting from lines 13-18 [unnamed-chunk-2] (test.Rmd)
Error in `device()`:
! arguments inutilisés (units = "in", res = 96)
Backtrace:
1. gganimate::animate(p)
2. gganimate:::animate.gganim(p)
4. gganimate (local) `<fn>`(...)
Exécution arrêtée
So we see here that no knit_print
method used. The issue is there
https://github.com/thomasp85/gganimate/blob/7cd46dc2bc8cf18c1c81f6ef7fc4d00a1d57a385/R/animate.R#L213
knitr::opts_chunk$get()
is used, which does not account for chunk level option. knitr::opts_currents$get()
should be used.
Issue shoud be opened upstream: https://github.com/thomasp85/gganimate
I'll do it from the above.
issues have been opened upstream. I'll close this here. You should subscribe to those two issues in gganimate repo to know when this will be resolved.