Skip to content

Instantly share code, notes, and snippets.

@leonawicz
Last active February 28, 2019 18:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save leonawicz/c6e051997170a90fc28f13eebad14423 to your computer and use it in GitHub Desktop.
Save leonawicz/c6e051997170a90fc28f13eebad14423 to your computer and use it in GitHub Desktop.
memery + rayshader
library(rayshader)
library(magick)
img <- image_read("meme_plot.gif")
n <- 36
phivec = 50 + 40 * 1/(1 + exp(seq(-2, 10, length.out = n) * 2))
thetavec = -44 + 45 * 1/(1 + exp(seq(-2, 10, length.out = n) * 2))
zoomvec = 0.6 + 0.25 * 1/(1 + exp(seq(-2, 10, length.out = n) * 2))
focusvec = 0.55 + -0.2 * 1/(1 + exp(seq(-4, 8, length.out = n) / 2))
for(i in 1:n){
x0 <- aperm(as.array(image_data(img, frame = i)), c(3, 2, 1))
x <- array(NA, dim(x0))
x[] <- as.integer(x0[]) / 255
elmat = matrix(0, nrow = nrow(x0), ncol = ncol(x0))
plot_3d(x, t(elmat), soliddepth = -50, windowsize = c(1000, 1000),
background = "#FFD39B", shadowdepth = -200,
shadowcolor = "#8B7355", shadowwidth = 100)
render_camera(phi = phivec[i], theta = thetavec[i], zoom = zoomvec[i], fov = 0)
render_depth(focus = focusvec[i], focallength = 18,filename = glue::glue("frame{i}"))
rgl::rgl.close()
}
img_frames <- paste0("frame", 1:n, ".png")
image_write_gif(image_read(img_frames), path = "meme_plot_rayshader.gif", delay = 1/7.5)
# NOTES: meme gif will be slower than necessary until I push the next memery package update
# to GitHub/CRAN to reflect more recent changes in the magick package.
# Also, I do not know how to produce an unoptimized gif with magick (someone please tell me if there is a way!)
# so after making the gif here, I have to de-optimize it using an online tool before I can actually use the file
# effectively in the rayshader script. (Otherwise you get the lossy image from frame to frame in the final result.)
# I began with this gif: https://thumbs.gfycat.com/FeistyMilkyGalapagospenguin-size_restricted.gif
# I removed the optimization (coalesced) here: https://ezgif.com/optimize and used the resulting version in the rayshader script.
# This was only needed because the source gif was optimzed.
library(ggplot2)
library(memery)
# animated gif
file <- "original.gif"
# some data
y <- as.numeric(JohnsonJohnson)
x <- seq_along(y)
type <- rep(1:4, length = length(x))
d <- data.frame(x = x, y = y, Type = factor(type, labels = c("Simple", "Not simple", "Magic", "Science")))
# a plot
p <- ggplot(d, aes(x, y, color = Type)) +
geom_smooth(aes(Type = NULL), method = "loess", colour = "white", size = 1, se = FALSE) +
geom_point(size = 3) +
scale_color_manual(values = c("darkred", "orange", "cornflowerblue", "darkorchid1")) +
labs(title = "A simple plot, on a simple gif", x = "Time index", y = "Memes produced",
caption = "Figure 1. With perspective, and extruded, simply so.")
# meme plot specifications
pos <- list(w = 0.4, h = 0.95, x = 0.79, y = 0.5)
vp_bg <- list(fill = "#FFD39B50", col = "#8B0000")
lab <- c("One does not simply", "Meme, plot, map, texture, 3D animate, and double gif")
lab_pos <- list(w = rep(0.5, 2), h = rep(0.3, 2), x = c(0.225, 0.36), y = c(0.9, 0.1))
# make meme plot animated gif
meme_gif(file, lab, "meme_plot.gif", size = c(1.6, 1),
col = c("#FFD39B", "#8B0000"), shadow = c("black", "white"),
label_pos = lab_pos, inset = p, inset_pos = pos, inset_bg = vp_bg, mult = 2,
frame = round(seq(1, 118, length.out = 36)), fps = 10) # source gif has 118 frames, don't need that many
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment