Created
July 28, 2016 08:44
-
-
Save expersso/944f3d4aad15f71b192fff254d4ac5b9 to your computer and use it in GitHub Desktop.
Trigonometry with magick, gganimate, and purrr
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## Purpose: illustrate use of magick, gganimate, and purrr | |
## Inspiration: | |
## https://rud.is/b/2016/07/27/u-s-drought-animations-with-the-witchs-brew-purrr-broom-magick/ | |
## and subsequent discussion on magick vs gganimate: | |
## https://twitter.com/hrbrmstr/status/758304420224466944 | |
library(purrr) | |
library(ggplot2) | |
library(gganimate) | |
library(animation) | |
library(magick) | |
# Sequence from 0 to 2pi (= radius of unit circle) | |
df <- data.frame(x = seq(0, 2 * pi, length.out = 100)) | |
# Create breaks and breaks labels at fractional intervals of pi | |
breaks <- seq(0, 2, 0.5) | |
breaks_lbls <- sprintf("%s * pi", as.character(breaks)) %>% | |
map(~parse(text = .x)) %>% | |
lift(c)(.) | |
# Animated plot of sin(x) and cos(x) from 0 to 2pi | |
p_trig <- ggplot(df, aes(x = x, frame = x, cumulative = TRUE)) + | |
geom_line(aes(y = sin(x), color = "sin(x)")) + | |
geom_line(aes(y = cos(x), color = "cos(x)")) + | |
scale_x_continuous(breaks = breaks * pi, | |
labels = breaks_lbls, | |
expand = c(0, 0)) + | |
scale_y_continuous(expand = c(0, 0.01)) + | |
theme_light() + | |
theme(panel.grid.minor = element_blank()) + | |
labs(x = "\nx", y = "f(x)\n", color = NULL) | |
# Generate DF of XY-coordinates of a circle with a given radius and center | |
circle <- function(t, r = 1, center = c(0, 0)) { | |
x <- center[1] + r * cos(t) | |
y <- center[2] + r * sin(t) | |
data.frame(x, y, id = seq_along(t)) | |
} | |
df_circle <- circle(df$x) | |
# Animated plot of unit circle, making a full revolution | |
p_unit_circle <- ggplot(df_circle, aes(x, y, yend = y, xend = x)) + | |
geom_hline(yintercept = 0, color = "grey80", linetype = "dashed") + | |
geom_vline(xintercept = 0, color = "grey80", linetype = "dashed") + | |
geom_path(color = "grey30") + | |
geom_segment(aes(x = 0, y = 0, frame = id), color = "grey80") + | |
geom_segment(aes(x = x, y = 0, frame = id, color = "sin(x)")) + | |
geom_segment(aes(x = 0, y = y, frame = id, color = "cos(x)")) + | |
scale_x_continuous(breaks = c(-1, 0, 1), expand = c(0, 0.01)) + | |
scale_y_continuous(breaks = c(-1, 0, 1), expand = c(0, 0.01)) + | |
coord_equal() + | |
theme_light() + | |
theme(panel.grid = element_blank(), legend.position = "none") + | |
labs(x = "\nx", y = "y\n") | |
# Save animated plots as GIFs | |
ani.options(ani.height = 130, interval = 0.001) | |
gg_animate(p_trig, "trig.gif", title_frame = FALSE, ani.width = 500) | |
gg_animate(p_unit_circle, "unit_circle.gif", title_frame = FALSE, ani.width = 130) | |
# Read the two plots and append together | |
map2( | |
"unit_circle.gif" %>% image_read() %>% as.list(), | |
"trig.gif" %>% image_read() %>% as.list(), | |
~image_append(c(.x, .y)) | |
) %>% | |
lift(image_join)(.) %>% | |
image_write("result.gif") | |
# Remove intermediate files | |
c("trig.gif", "unit_circle.gif") %>% walk(unlink) | |
# Easier than doing it the old-fashioned way: | |
# shell( | |
# paste( | |
# "convert", | |
# "\\( unit_circle.gif -coalesce -append \\)", | |
# "\\( trig.gif -coalesce -append \\)", | |
# "+append -crop x130 -set delay 0.01 +repage result.gif" | |
# ) | |
# ) |
Author
expersso
commented
Jul 28, 2016
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment