본문 바로가기
R

gganimate 패키지로 신년 메세지 동영상만들기

by 슬통이 2022. 1. 2.
반응형

새로운 새해가 밝았습니다. 22년 호랑이의 기운이 솟아나는 힘찬 한해가 되었으면 좋겠습니다! 오늘 만들어본 것은 이제까지 tidyverse 마스터클래스에서 배웠던 gganimate과 ggplot font를 사용해서 신년 축하 동영상을 만들어 보았습니다.

 

영상의 기본틀을 이루는 코드는 gganimate 패키지 제작자의 불꽃놀이 코드에서 훔쳐왔습니다. 저는 불꽃이 터지는 위치와 메세지가 겹치지 않도록 살짝 숟가락만 얹었습니다.ㅋㅋ 원본 코드가 들어있는 포스트는 다음과 같습니다.

https://www.data-imaginist.com/2019/gganimate-has-transitioned-to-a-state-of-release/

 

gganimate has transitioned to a state of release

After being the primary focus of my spare time for almost a year, gganimate has finally landed on CRAN. I hope you'll enjoy using it as much as I've enjoyed developing it.

www.data-imaginist.com

결과물

 

R 코드

영상 제작에 쓰인 코드는 다음과 같습니다.

# https://www.data-imaginist.com/2019/gganimate-has-transitioned-to-a-state-of-release/
# Happy New Year
library(tidyverse)
library(gganimate)
library(png)
library(grid)
img <- readPNG("./img/black-tiger.png") # 원하는 사진을 준비~!
g <- rasterGrob(img, interpolate=TRUE)

# Firework colours
colours <- c(
    'lawngreen', 'gold',
    'white', 'orchid', 'royalblue',
    'yellow', 'orange'
)

# Produce data for a single blast
blast <- function(n, radius, x0, y0, time) {
    rho <- runif(n, 0, 2*pi)
    u <- runif(n, 0, 1)
    x_prime <- cos(rho)
    y_prime <- sin(rho)
    x <- x0 + (radius * x_prime * sqrt(1 - u^2)) # radius adjust
    y <- y0 + (radius * y_prime * sqrt(1 - u^2))
    id <- sample(.Machine$integer.max, n + 1)
    data.frame(
        x = c(x0, rep(x0, n), x0, x),
        y = c(0, rep(y0, n), y0, y),
        id = rep(id, 2),
        time = c((time - y0) * runif(1), rep(time, n), time, time + radius + rnorm(n)),
        colour = c('white', rep(sample(colours, 1), n), 'white', rep(sample(colours, 1), n)),
        stringsAsFactors = FALSE
    )
}

library(extrafont)
# import_font()
# loadfonts(device = "win")
font_import(pattern = "PWHappyChristmas",
            prompt = FALSE)

# Make 20 blasts
n <- round(rnorm(20, 30, 4))
radius <- round(n)

rho <- runif(n, 0, pi)
x_prime <- cos(rho) * 35
y_prime <- sin(rho) * 35
x0 <- x_prime
y0 <- y_prime + 60
time <- runif(20, max = 100)
fireworks <- Map(blast, n = n, radius = radius, x0 = x0, y0 = y0, time = time)
fireworks <- bind_rows(fireworks)

ggplot(fireworks) + 
    geom_point(aes(x, y, colour = colour, group = id), size = 1, shape = 20) + 
    annotation_custom(g, xmin=-37, xmax=23, ymin=0, ymax=30) +
    scale_colour_identity() + 
    coord_fixed(xlim = c(-65, 65), expand = FALSE, 
                clip = 'off') +
    theme_void() + 
    theme(plot.background = element_rect(fill = 'black', colour = NA),
          panel.border = element_blank()) +
    annotate("text", 0, 70,
             label = "Happy \n New Year!",
             family = "PWJoyeuxNoel",
             size = 30,
             color = "white") +
    annotate("text", 0, 35,
             label = "새해 복 많이 받으세요~! \n 슬기로운 통계생활",
             size = 15,
             family = "GangwonEduPower",
             color = "white") +
    # Here comes the gganimate code
    transition_components(time, exit_length = 20) + 
    ease_aes(x = 'sine-out', y = 'sine-out') + 
    shadow_wake(0.05, size = 3, alpha = TRUE, wrap = FALSE, 
                falloff = 'sine-in', exclude_phase = 'enter') + 
    exit_recolour(colour = 'black')
반응형

댓글