Nova
Nova

Reputation: 5891

Consistent size for symbols in ggsave and gganimate's 'animate'

My end goal is to create two outputs:

1) A static image showing all of my data, saved as a png
2) An animation of my data, saved as a gif.

I'm using ggplot2 and gganimate and I'm puzzled as to why the symbol size is not consistent between the two save methods.

I've tried adjusting the dpi and saving as jpg instead of png, but no luck. Can anyone help me figure out how to make the width, height, and symbol size in both output objects consistent?

Here's a reproducible example showing both outputs. You can see that the black points are smaller in the gif.

Make the png

library(gganimate)
library(ggplot2)

locs <- data.frame(x = c(1, 2, 3, 4, 5, 6),
                   y = c(1, 2, 3, 3.1, 3.2, 6),
                   LDT = c(1, 2, 3, 4, 5, 6))

g <- ggplot(locs, aes(x, y)) +
  geom_point() +
  theme_void() +
  theme(plot.background = element_rect(fill = "pink"))
g
ggsave("test.png", g, width = 2, height = 2, dpi = 100)

enter image description here

Make the gif

anim <- g + transition_time(LDT)
animate(anim, duration = 1, fps = 20, width = 200, height = 200)
anim_save("test.gif")

enter image description here

Upvotes: 2

Views: 693

Answers (1)

ismirsehregal
ismirsehregal

Reputation: 33510

animate() by default uses png() to generate frames.

In your ggsave call you specified a plot resolution of 100 dpi.

To get the same result using png you'll have to set res = 100 (see test_png_device.png).

Accordingly to have a consistent symbol size using animate you'll have to pass the resolution to png as an optional argument to animate as follows:

library(gganimate)
library(ggplot2)
library(gifski)

locs <- data.frame(x = c(1, 2, 3, 4, 5, 6),
                   y = c(1, 2, 3, 3.1, 3.2, 6),
                   LDT = c(1, 2, 3, 4, 5, 6))

g <- ggplot(locs, aes(x, y)) +
  geom_point() +
  theme_void() +
  theme(plot.background = element_rect(fill = "pink"))

ggsave("test.png", g, width = 2, height = 2, dpi = 100)

png(filename = "test_png_device.png", width = 200, height = 200, units = "px", res = 100)
g
dev.off()

anim <- g + transition_time(LDT)
myAnimation <- animate(anim, duration = 1, fps = 20, width = 200, height = 200, renderer = gifski_renderer(), res = 100)
anim_save("test.gif", animation = myAnimation)

ggsaveResult


Addition: Not sure if you are interested in this, however, I like using library(plotly) for animations since it adds an animation slider by default.

Here is the ggplotly-way for your example:

library(plotly)
library(htmlwidgets)

locs <- data.frame(x = c(1, 2, 3, 4, 5, 6),
                   y = c(1, 2, 3, 3.1, 3.2, 6),
                   LDT = c(1, 2, 3, 4, 5, 6))

g <- ggplot(locs, aes(x, y)) + theme_void() + 
  theme(panel.background = element_rect(fill = "pink")) +
  geom_point(aes(frame = LDT))

p <- ggplotly(g) %>% 
  animation_opts(500, easing = "linear", redraw = FALSE)

saveWidget(p, file = "myAnimation.html", selfcontained = TRUE)
browseURL("myAnimation.html")

Here a related post can be found.

Upvotes: 3

Related Questions