Animating generative art - R, generativeart and gganimate

Nov 7, 2020 00:00 · 555 words · 3 minute read art generativeart animation

Generative art is art created through the autonomous system. Typically it means the use of some algorithm, but it is not limited to creations created with computer.

Generative art is, for me, an element of the hyperhuman toolkit. It’s a technology that allows (due to the low entry barrier) to explore oneself through art.

Today I wanted to play a bit with R package generativeart. Through the use of simple sine functions, it can generate images like this:

or this:

See the website of generativeart package for more examples.

I wanted to animate the plot to overlay the sound effects on the plot as it appears in front of my eyes. Let’s go through the process step by step.

Building the plot

Below is a slightly expanded copy of the code supplied by Katharina Brunner, the author of generativeart package.

Let’s load the necessary libraries first. If you don’t have them, you need to install them with install.packages function.

library(generativeart)
library(gganimate)
library(av)

Now, it is necessary to set up directories for outputs. I use mkdir -p bash command to run it without fail if the directory already exists.

system("mkdir -p img")
system("mkdir -p img/everything")
system("mkdir -p img/handpicked")
IMG_DIR <- "img/"
IMG_SUBDIR <- "everything/"
IMG_SUBDIR2 <- "handpicked/"
IMG_PATH <- paste0(IMG_DIR, IMG_SUBDIR)

system("mkdir -p logfile")
LOGFILE_DIR <- "logfile/"
LOGFILE <- "logfile.csv"
LOGFILE_PATH <- paste0(LOGFILE_DIR, LOGFILE)

# create the directory structure
generativeart::setup_directories(IMG_DIR, IMG_SUBDIR, IMG_SUBDIR2, LOGFILE_DIR)
## [1] NA

Let’s use the formula Katharina provides in the README.

my_formula <- list(
  x = quote(runif(1, -1, 1) * x_i^2 - sin(y_i^2)),
  y = quote(runif(1, -1, 1) * y_i^3 - cos(x_i^2))
)

generativeart::generate_img(formula = my_formula, nr_of_img = 1, polar = TRUE, filetype = "png", color = "black", background_color = "white")
## [1] "load logfile"
## [1] "logfile saved"
## [1] "generate data"
## [1] "generate plot"
## [1] "image saved..."
## [[1]]
## [1] "image saved..."

The resulting file is shown below.

Animation

We need to save data to feed it into a gganimate package, so I will use generate_data function to save the plot data. Then I will use the exact plotting routine from generativeart package and build animation with it.

# save the data to an object

my.df <- generativeart::generate_data(my_formula)
## [1] "generate data"
# this is how generativeart package does its plots (extracted from generate_img function)

color <- "black"
background_color <- "white"

plot <- my.df %>%
  ggplot2::ggplot(ggplot2::aes(x = x, y = y)) +
  ggplot2::geom_point(alpha = 0.1, size = 0, shape = 20, color = color) +
  ggplot2::theme_void() +
  ggplot2::coord_fixed() +
  ggplot2::coord_polar() +
  ggplot2::theme(
    panel.background = element_rect(fill = background_color),
    plot.background = element_rect(fill = background_color)
  )

I need to annotate every 1000 consecutive points with frame numbers to build an animation using this assignment.

# now, we need to split the data into frames (1000 points at the time)

n.rows <- nrow(my.df)
n.frames <- round(n.rows/1000) + 1 
frames <- 1:n.frames
frames.rows <- rep(frames, each = 1000)
my.df$frame.list <- frames.rows[1:n.rows]

# let's build an animation object

animation <- plot + transition_manual(factor(my.df$frame.list), cumulative = TRUE)

Now finally the animation part (this one took an hour on my computer):

animate(
  animation,
  width = 1000, height = 800, res = 35, fps = 24, nframes = 500, renderer = av_renderer(file = "example_animation.mp4")
)

The resulting animation starts similarly to the one below:

Now, let’s see if I can add decent sounds effects to this…