class: center, middle, inverse, title-slide # generative art ### 2021-11-19 --- class: middle, inverse # Welcome --- ## Announcements - Dec 1: AMA with Thomas Lin Pedersen - Topic: Anything ggplot2 or data visualization - To prepare: Just keep doing what you're doing! - Add a question to sli.do by 11:30am on Dec 1: [sli.do](https://slido.com/) / #632366 (will be open Nov 25) -- - Office hours for the week of Thanksgiving: - Mine: 3:30-4:30pm on Monday (virtual) - Vittorio: 2-3pm on Monday + 11am-12pm on Tuesday (both virtual) - Office hours for last week of classes: - Vittorio: 2-3pm on Monday + 11am-12pm on Tuesday (both in person at Old Chem 203B) - Jennifer: 3-4pm on Wednesday and 5-6pm on Thursday (both virtual) - Mine: 3-4pm on Tuesday and 3:30-5pm on Thursday (both virtual) -- - Remaining items due: - RQ 6 - Wed, 24 Nov - HW 6 - Mon, 29 Nov - Project 2 - Fri, 3 Dec --- ## Setup .midi[ ```r # load packages library(tidyverse) library(scico) # set default theme (use theme_gray) ggplot2::theme_set(ggplot2::theme_gray(base_size = 16)) # set default figure parameters for knitr knitr::opts_chunk$set( fig.width = 8, fig.asp = 0.618, fig.retina = 3, dpi = 300, out.width = "60%" ) # dplyr print min and max options(dplyr.print_max = 6, dplyr.print_min = 6) ``` ] --- class: middle, inverse # Generative art --- ## Genesis 338 by Thomas Lin Pedersen <img src="images/genesis338.png" width="60%" /> [More from Thomas Lin Pedersen](https://www.data-imaginist.com/art) --- ## Flametree by Danielle Navarro <img src="images/flametree.png" width="40%" /> [More from Danielle Navarro](https://art.djnavarro.net/) --- ## Permutations by Georgios Karamanis <img src="images/permutations.png" width="25%" /> [More from Georgios Karamanis](https://karaman.is/) --- ## Abstractions by Antonio Sánchez Chinchón <img src="images/abstractions.png" width="40%" /> [More from Antonio Sánchez Chinchón](https://fronkonstin.com/) --- ## Generative art: what > One overly simple but useful definition is that generative art is art programmed using a computer that intentionally introduces randomness as part of its creation process. > >[Jason Bailey](https://www.artnome.com/news/2018/8/8/why-love-generative-art) - There is randomness to the art, introduced by the computer (the code) - The artist has control over the randomness, as contradictory as that may sound --- ## Generative art: why - Why people create generative art pieces? - Artistic expression - Leveraging computers to generate randomness - ... -- - Why are we learning about generative art? - A different look at data visualization: not for the meaning in the data, but for the visual itself - Great way to practice programming, particularly if you're into creating art - Opportunity to practice problem solving skills, particularly if you're sketching first, then creating or reproducing an existing piece --- ## Generative art in use: Book covers Just one of many examples of generative art as a practical solution by the New York Public Library: To fill in missing book covers in an ebook-borrowing and reading app <img src="images/Generative-book-covers.png" width="60%" /> .footnote[ New York Public Library, [Generative eBook Covers](https://www.nypl.org/blog/2014/09/03/generative-ebook-covers). September 3, 2014. ] --- class: middle, inverse # Flowers in the (plot) window --- ## Let's make a circle .pull-left[ ```r # make a circle of points t <- seq(0, 2 * pi, length.out = 50) x <- sin(t) y <- cos(t) df <- tibble(t, x, y) # plot a circle of points ggplot(df, aes(x, y)) + geom_point() + coord_equal() ``` ] .pull-right[ <img src="22-generative-art_files/figure-html/unnamed-chunk-7-1.png" width="100%" /> ] --- ## The Golden Angle .pull-left[ The golden angle is the angle subtended by the smaller (red) arc when two arcs that make up a circle are in the golden ratio. $$ \pi(3 − \sqrt{5}) $$ <img src="images/Golden_Angle.png" width="50%" style="display: block; margin: auto;" /> ] -- .pull-right[ The golden angle is the angle separating successive florets on a sunflower. <img src="images/Goldener_Schnitt_Blattstand.png" width="50%" style="display: block; margin: auto;" /> ] .footnote[ Wikipedia. [Golden angle](https://en.wikipedia.org/wiki/Golden_angle). ] --- ## Petals with the golden angle .pull-left[ ```r # set golden angle angle <- pi * (3 - sqrt(5)) # set number of points points <- 50 # make data frame df <- tibble( i = 1:points, t = (1:points) * angle, x = sin(t), y = cos(t) ) # plot points in a spiral ggplot(df, aes(x = x * t, y = y * t)) + geom_path(color = "gray") + geom_text(aes(label = i)) + coord_equal() ``` ] .pull-right[ <img src="22-generative-art_files/figure-html/unnamed-chunk-10-1.png" width="100%" /> ] --- ## Paths to points .pull-left[ ```r # set golden angle angle <- pi * (3 - sqrt(5)) # set number of points points <- 50 # make data frame df <- tibble( i = 1:points, t = (1:points) * angle, x = sin(t), y = cos(t) ) # plot points in a spiral ggplot(df, aes(x = x * t, y = y * t)) + * geom_point() + coord_equal() ``` ] .pull-right[ <img src="22-generative-art_files/figure-html/unnamed-chunk-11-1.png" width="100%" /> ] --- ## Without the background .pull-left[ ```r # set golden angle angle <- pi * (3 - sqrt(5)) # set number of points points <- 50 # make data frame df <- tibble( i = 1:points, t = (1:points) * angle, x = sin(t), y = cos(t) ) # plot points in a spiral ggplot(df, aes(x = x * t, y = y * t)) + geom_point() + coord_equal() + * theme_void() ``` ] .pull-right[ <img src="22-generative-art_files/figure-html/unnamed-chunk-12-1.png" width="100%" /> ] --- ## More points .pull-left[ ```r # set golden angle angle <- pi * (3 - sqrt(5)) # set number of points *points <- 100 # make data frame df <- tibble( i = 1:points, t = (1:points) * angle, x = sin(t), y = cos(t) ) # plot points in a spiral ggplot(df, aes(x = x * t, y = y * t)) + geom_point() + coord_equal() + theme_void() ``` ] .pull-right[ <img src="22-generative-art_files/figure-html/unnamed-chunk-13-1.png" width="100%" /> ] --- ## Adjust points .pull-left[ ```r # set golden angle angle <- pi * (3 - sqrt(5)) # set number of points points <- 100 # make data frame df <- tibble( i = 1:points, * t = (1:points) * angle + 20, x = sin(t), y = cos(t) ) # plot points in a spiral ggplot(df, aes(x = x * t, y = y * t)) + geom_point() + coord_equal() + theme_void() ``` ] .pull-right[ <img src="22-generative-art_files/figure-html/unnamed-chunk-14-1.png" width="100%" /> ] --- class: middle, inverse # Formalize a system --- ## Write a function: `build_art()` ```r build_art <- function() { # set golden angle angle <- pi * (3 - sqrt(5)) # set number of points points <- 100 # make data frame tibble( i = 1:points, t = (1:points) * angle + 20, x = sin(t), y = cos(t) ) } ``` --- ## Add arguments to `build_art()` .pull-left[ ```r build_art <- function(points, angle, adjustment) { tibble( i = 1:points, t = (1:points) * angle + adjustment, x = sin(t), y = cos(t) ) } ``` ] .pull-right[ ```r build_art( angle = pi * (3 - sqrt(5)), points = 100, adjustment = 20 ) ``` ``` ## # A tibble: 100 × 4 ## i t x y ## <int> <dbl> <dbl> <dbl> ## 1 1 22.4 -0.398 -0.918 ## 2 2 24.8 -0.327 0.945 ## 3 3 27.2 0.879 -0.476 ## 4 4 29.6 -0.970 -0.243 ## 5 5 32.0 0.551 0.834 ## 6 6 34.4 0.157 -0.988 ## # … with 94 more rows ``` ] --- ## Use the function .pull-left[ ```r build_art( angle = pi * (3 - sqrt(5)), points = 100, adjustment = 20 ) %>% ggplot(aes(x = x * t, y = y * t)) + geom_point() + coord_equal() + theme_void() ``` ] .pull-right[ <img src="22-generative-art_files/figure-html/unnamed-chunk-18-1.png" width="100%" /> ] --- ## Change parameters .pull-left[ ```r build_art( * angle = 3, * points = 500, * adjustment = 0 ) %>% ggplot(aes(x = x * t, y = y * t)) + geom_point() + coord_equal() + theme_void() ``` ] .pull-right[ <img src="22-generative-art_files/figure-html/unnamed-chunk-19-1.png" width="100%" /> ] --- ## Next steps... - Add random noise - Add more customization options - Size - Color - Shape - ... --- class: middle, large .hand[livecoding...] (See next few slides for code developed during the livecoding session in class.) --- ## Function: `build_art()` ```r build_art <- function(points, angle = pi * (3 - sqrt(5)), adjustment = 0, sd = 0.02, seed) { set.seed(seed) tibble( i = 1:points, t = (1:points) * angle + adjustment, x = sin(t), y = cos(t) ) %>% mutate( x_shift = rnorm(n = points, sd = sd), y_shift = rnorm(n = points, sd = sd), x = x + x_shift, y = y + y_shift ) } ``` --- ## Function: `draw_art()` ```r draw_art <- function(df, shape, alpha = 0.5, ...){ ggplot(df, aes(x = x * t, y = y * t)) + geom_point(aes(size = t, color = t, fill = t), shape = shape, alpha = alpha, show.legend = FALSE) + coord_equal() + theme_void() + scale_fill_scico(...) + scale_color_scico(...) + facet_wrap(~flower) + theme(strip.text = element_blank()) } ``` --- ## A grid of flowers .panelset.sideways[ .panel[.panel-name[Code] ```r map_dfr(.x = round(runif(9, min = 0, max = 1000)), ~build_art( points = 200, angle = 1, sd = 0.05, seed = .x), .id = "flower") %>% draw_art(shape = "square filled", palette = "batlow", alpha = 0.6, direction = -1) ``` ] .panel[.panel-name[Plot] <img src="22-generative-art_files/figure-html/unnamed-chunk-22-1.png" width="70%" /> ] ] --- ## A grid of flowers, with some changes .panelset.sideways[ .panel[.panel-name[Code] ```r map_dfr(.x = round(runif(9, min = 0, max = 1000)), ~build_art( points = 200, angle = 1, sd = 0.05, seed = .x), .id = "flower") %>% draw_art(shape = "triangle down filled", palette = "berlin", alpha = 0.6, direction = 1) ``` ] .panel[.panel-name[Plot] <img src="22-generative-art_files/figure-html/unnamed-chunk-23-1.png" width="70%" /> ] ] --- ## A grid of flowers, with more customization .panelset.sideways[ .panel[.panel-name[Code] ```r n_flowers = 9 list_of_parameters <- list( points = sample(seq(300, 500, 50), n_flowers, replace = TRUE), angle = sample(c(1, 2, 3), n_flowers, replace = TRUE), sd = sample(c(0.01, 0.02, 0.03), n_flowers, replace = TRUE), seed = round(runif(n_flowers, min = 0, max = 1000)) ) pmap_dfr(list_of_parameters, build_art, .id = "flower") %>% draw_art(shape = "triangle down filled", palette = "berlin", alpha = 0.6, direction = 1) ``` ] .panel[.panel-name[Plot] <img src="22-generative-art_files/figure-html/unnamed-chunk-24-1.png" width="70%" /> ] ] --- class: middle, inverse # Wrap up --- ## Acknowledgements - [Unpredictable paintings](https://blog.djnavarro.net/posts/2021-11-01_unpredictable-paintings/) by Danielle Navarro - [Drawing Flowers with R and ggplot2](https://roweyerboat.github.io/drawing_flowers_with_r_and_ggplot2) by Amanda Rowe - [Generative Art and R](https://generative.substack.com/p/generative-art-and-r) by the Generative Arts Collective - [Getting Started with Generative Art in R](https://towardsdatascience.com/getting-started-with-generative-art-in-r-3bc50067d34b) - [Why Love Generative Art?](https://www.artnome.com/news/2018/8/8/why-love-generative-art) by Jason Bailey --- ## Learn/do more - R packages: - [aRtsy](https://koenderks.github.io/aRtsy/) by Koen Derks - [generativeart](https://github.com/cutterkom/generativeart) by Katharina Brunner - [flametree](https://flametree.djnavarro.net/) and [jasmines](https://jasmines.djnavarro.net/) bu Danielle Navarro - [ambient](https://ambient.data-imaginist.com/) and [particles](https://github.com/thomasp85/particles) by Thomas Lin Pedersen - More aRtists: [rtistry art gallery](https://ijeamaka-a.shinyapps.io/rtistry_gallery/) by Ijeamaka Anyene - Community: [Recreation Thursday](https://github.com/sharlagelfand/RecreationThursday) - [#RecreationThursday](https://twitter.com/search?q=%23RecreationThursday&src=typed_query&f=live) is a summer social project for data visualization folks to recreate and remix existing art pieces through any medium of their choosing - through code, painting, music, embroidery, whatever! Our goal is to get creativity flowing and most importantly to have fun!