Created
November 14, 2018 08:42
-
-
Save beemyfriend/4d448f0e2ed82993b5e5ad2acabe1fde to your computer and use it in GitHub Desktop.
ascii art animation
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
```{r, message=F} | |
library(tidyverse) | |
library(imager) | |
library(cowplot) | |
library(animation) | |
library(tweenr) | |
``` | |
```{r} | |
im <- load.image('Ortiz_Ulloa_Benjamin.jpg') | |
all_im <- 'satrdays_2018_photos/' %>% | |
str_c(., dir(.)) %>% | |
map_il(function(x){ | |
load.image(x) %>% | |
resize(400, 400) %>% | |
rm.alpha() | |
}) | |
map(all_im, ~plot(print(.))) | |
``` | |
```{r} | |
speakers_info <- tibble( | |
name = c("Daniel Chen", | |
"David Meza", | |
"Benjamin Harvey", | |
"Gwynn Sturdevant", | |
"Helen Levy-Myers", | |
"Martin Skarzynski", | |
"Matthew Hendrickson", | |
"Michael Lee", | |
"Minh Tran", | |
"Kelly O'Briant", | |
"Katherine Ognyanova", | |
"Benjamin Ortiz Ulloa", | |
"David Smith", | |
"Charlie Thompson", | |
"Tony McGovern", | |
"Tyler Morgan-Wall", | |
"Wendy Wong"), | |
title = c("TBD", | |
"Understanding the International Space Station Crew\n Perspective Following Long Duration Missions:\n Data Analytics and Visualization of Crew Feedback", | |
"TBD", | |
"TBD", | |
"Influencing Factors on \nHigh School Graduation", | |
"How to Write Respectful\n and Empathic Code and Documentation", | |
"Learning R by Doing", | |
"Animate All the Things:\n Methods for Animated Visualization in R", | |
"Time-Series Regressions:\n What Are They & Why Would I Use Them", | |
"Co-Organizer", | |
"TBD", | |
"Co-Organizer", | |
"TBD", | |
"TBD", | |
"Spatial Data Analysis in Power BI: \nFrom Beautiful Thematic Maps to R-Based Models", | |
"3D Mapping, Plotting, and Printing \n with Rayshader", | |
"How to Run RStudio Servers Anywhere\n with Containers - HPC, Cloud, and Locally"), | |
img = all_im | |
) | |
``` | |
```{r} | |
existing_talks <- speakers_info %>% | |
filter(title != 'TBD') | |
``` | |
```{r} | |
asc <- gtools::chr(38:126) | |
g.chr <- function(chr) { | |
implot(imfill(50, 50, val = 1), | |
text(25, 25, chr, cex = 5)) %>% | |
grayscale() %>% | |
mean() | |
} | |
g <- map_dbl(asc, g.chr) | |
n <- length(g) | |
plot(1:n, sort(g), type ='n', xlab='Order', ylab = 'lightness') | |
text(1:n, sort(g), asc[order(g)]) | |
``` | |
```{r} | |
char <- asc[order(g)] | |
char_key <- char %>% | |
unique %>% | |
{names(.) <- .; .} | |
existing_talks <- existing_talks %>% | |
mutate(d = map(img, function(x){ | |
temp_df <- x %>% | |
imresize(.2) %>% | |
grayscale() %>% | |
as.data.frame() %>% | |
mutate(qv = cut(value, n) %>% as.integer, | |
char = char[qv]) | |
})) | |
``` | |
```{r} | |
n_clr <- 10 | |
shade_key <- seq(0, 1, length.out = n_clr) | |
existing_talks <- existing_talks %>% | |
mutate(d_clr = map(img, function(x){ | |
x %>% | |
imresize(.2) %>% | |
as.data.frame() %>% | |
mutate(value = cut(value, n_clr) %>% as.integer(), | |
value = shade_key[value]) %>% | |
mutate(cc = paste0('cc_', cc)) %>% | |
group_by(x,y) %>% | |
spread(cc, value) %>% | |
ungroup() %>% | |
mutate(rgb = rgb(cc_1, cc_2, cc_3)) | |
})) | |
``` | |
```{r} | |
existing_talks <- existing_talks %>% | |
mutate(all_d = map2(d, d_clr, function(d, d_clr){ | |
left_join(d_clr, select(d, x, y, char, value), by = c('x', 'y')) | |
})) %>% | |
select(-d, -d_clr) | |
``` | |
```{r} | |
existing_talks$all_d %>% | |
map(function(img){ | |
clr_key <- img$rgb %>% | |
{names(.) <- .; .} | |
ggplot() + | |
geom_point(aes(x,y, color = rgb, shape = char), img) + | |
scale_color_manual(values = clr_key) + | |
scale_shape_manual(values = char_key) + | |
scale_y_reverse() + | |
theme(legend.position = 'none') | |
}) | |
``` | |
```{r} | |
point_ascii_animation <- function(img, name, title, fading_point = 10, fading_color = 15, label_show = 25){ | |
print(str_glue("Started on {name}'s animation")) | |
disappearing_point <- img %>% | |
mutate(data = list( | |
tibble( | |
alpha = 1:fading_point, | |
size = 1:fading_point, | |
step = 1:fading_point | |
))) %>% | |
unnest() %>% | |
mutate(size = round(size, 2)) | |
staying_char <<- img %>% | |
mutate(data = list( | |
tibble( | |
alpha = 1, | |
size = 1, | |
step = 1:(fading_point * 1.5) | |
))) %>% | |
unnest() | |
tween_dictionary <<- img$rgb %>% | |
unique %>% | |
setNames(., .) %>% | |
map(~tween_color(c(.x, "#000000"), fading_color, 'linear')) | |
greying_char <<- img %>% | |
mutate(data = map2(value, rgb, function(x,y){ | |
tibble(rgb2 = tween_dictionary[[y]] %>% unlist()) %>% | |
mutate(step = (fading_point * 1.5 + 1):(fading_point* 1.5 + fading_color), | |
alpha = 1, #tween_numeric(c(1, 1-x), fading_color , 'linear') %>% unlist(), | |
size = 1) | |
})) %>% | |
unnest() %>% | |
mutate(rgb = rgb2) | |
clearing_char <<- img %>% | |
mutate(rgb = "#000000") %>% | |
mutate(data = map(value, function(x){ | |
tibble( | |
alpha = tween_numeric(c(1, 1-x), 5 , 'linear') %>% unlist(), | |
size = 1, | |
step = (fading_point*1.5 + fading_color + 1):(fading_point*1.5 + fading_color + 5) | |
) | |
})) %>% | |
unnest() | |
char_animation <<- bind_rows(staying_char, greying_char, clearing_char) %>% | |
select(x, y, rgb, alpha, size, char, step) | |
clr_key <- c(char_animation$rgb, disappearing_point$rgb) %>% | |
unique %>% | |
{names(.) <- .; .} | |
char_key <- char_animation$char %>% | |
unique %>% | |
{names(.) <- .; .} | |
size_key <- tween_numeric(c(2, 0), fading_point, 'linear') %>% | |
unlist() %>% | |
{names(.) <- 1:fading_point; . } | |
print(str_glue("finished data cleaning, now rendering animation")) | |
saveGIF({ | |
ani.options(interval = 0.1, ani.width = 500, ani.height = 500) | |
for (i in seq(max(char_animation$step))) { | |
to_show <- ggplot() + | |
scale_color_manual(values = clr_key) + | |
scale_shape_manual(values = char_key ) + | |
scale_size_manual(values = size_key) + | |
theme_void() + | |
theme(legend.position ='none') + | |
scale_y_reverse() | |
# print(str_glue("to_show {i} initiated")) | |
if(nrow(filter(char_animation, step == i)) > 0){ | |
to_show <- to_show + | |
geom_text(aes(x,y, color = rgb, label = char, size = '1', alpha = alpha ), | |
filter(char_animation, step == i)) | |
} | |
if(nrow(filter(disappearing_point, step == i)) > 0){ | |
to_show <- to_show + | |
geom_point(aes(x,y, color = rgb, alpha = alpha, size = as.character(size)), | |
filter(disappearing_point, step == i)) | |
} | |
print(to_show) | |
ani.pause() | |
} | |
temp_df <- char_animation %>% | |
filter(step == max(char_animation$step)) | |
mid_x <- median(temp_df$x) | |
min_y <- min(temp_df$y) | |
quar_2_y <- quantile(temp_df$y, .1) | |
quar_3_y <- quantile(temp_df$y, .9) | |
max_y <- max(temp_df$y) | |
# | |
# tween_title <- tween_numeric(c(min_y, quar_2_y), label_show) %>% unlist | |
# tween_name <- tween_numeric(c(max_y, quar_3_y), label_show) %>% unlist | |
title_letters <- title %>% | |
str_split('') %>% | |
unlist() | |
name_letters <- name %>% | |
str_split('') %>% | |
unlist() | |
max_i <- max(length(name_letters), length(title_letters)) | |
# for(i in seq(label_show)){ | |
for(i in seq(max_i)){ | |
temp_name <- ifelse(i > length(name_letters), | |
paste(name_letters, collapse = ''), | |
paste(name_letters[1:i], collapse = '')) | |
temp_title <- ifelse(i > length(title_letters), | |
paste(title_letters, collapse = ''), | |
paste(title_letters[1:i], collapse = '')) | |
print( | |
ggplot() + | |
geom_text(aes(x,y, alpha = alpha, label = char, size = "1"), temp_df, color = "#000000") + | |
scale_color_manual(values = clr_key) + | |
scale_size_manual(values = (size_key + .5)) + | |
scale_shape_manual(values = char_key) + | |
theme_void() + | |
theme(legend.position ='none') + | |
scale_y_reverse() + | |
annotate("label", x = mid_x, y = quar_2_y, label = temp_title, color = "blue", hjust = .5, vjust = 1, size = 7, label.padding = unit(0.5, "lines")) + | |
annotate("label", x = mid_x, y = quar_3_y, label = temp_name, color = "blue", hjust = .5, vjust = 0, size = 5, label.padding = unit(0.5, "lines")) | |
) | |
ani.pause() | |
} | |
print( | |
ggplot() + | |
geom_text(aes(x,y, alpha = alpha, label = char, size = "1"), temp_df, color = "#000000") + | |
scale_color_manual(values = clr_key) + | |
scale_size_manual(values = (size_key + .5)) + | |
scale_shape_manual(values = char_key) + | |
theme_void() + | |
theme(legend.position ='none') + | |
scale_y_reverse() + | |
annotate("label", x = mid_x, y = quar_2_y, label = title, color = "blue", hjust = .5, vjust = 1, size = 7, label.padding = unit(0.5, "lines")) + | |
annotate("label", x = mid_x, y = quar_3_y, label = name, color = "blue", hjust = .5, vjust = 0, size = 5, label.padding = unit(0.5, "lines")) | |
) | |
ani.pause(interval = 1) | |
}, movie.name = str_glue("{name} animation.gif")) | |
} | |
``` | |
```{r} | |
existing_talks %>% | |
filter(name == "David Meza") %>% | |
pmap(function(name,title, img, all_d){ | |
point_ascii_animation(all_d, name, title) | |
}) | |
``` | |
```{r} | |
existing_talks %>% | |
pmap(function(name,title, img, all_d){ | |
point_ascii_animation(all_d, name, title) | |
}) | |
``` |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment