class: center, middle, inverse, title-slide # > 🎨
> data visualisation with ggplot2 ###
Danielle Navarro
--- layout: true <div class="my-footer"> <!-- <span> <a href="https://robust-tools.djnavarro.net" target="_blank">robust-tools.djnavarro.net</a> </span> --> </div> --- class: middle, inverse ## https://rstudio.cloud/project/901338 ??? demo sequence: - explain RStudio layout - explain boring R text - ctrl-L to clear boring text (verbalise shortcut) - `library(tidyverse)`, explain messages - `mpg`, explain data - `?mpg`, explain "help" docs - clear screen again - `ggplot(data = mpg)`, explain each component while typing (use the word "function" early!) - discuss output (note the popups and explain them) - up arrow to recall last command (verbalise it) - `+ geom_point(mapping = aes(x = displ, y = hwy))` - talk them through this bit by bit, but "defer" explanation of `aes()` for now --- class: middle, inverse background-image: url("img/code.jpg") background-size: cover --- class: middle, inverse background-image: url("img/code.jpg") background-size: cover <img src="img/My_First_Plot1.png" width="500" height="500" style="display: block; margin: auto;" /> ??? - this is recap to solidify learning - `ggplot()` creates the (still blank) plot using `data = mpg` --- class: middle, inverse background-image: url("img/code.jpg") background-size: cover <img src="img/My_First_Plot2.png" width="500" height="500" style="display: block; margin: auto;" /> --- class: middle, inverse background-image: url("img/code.jpg") background-size: cover <img src="img/My_First_Plot3.png" width="500" height="500" style="display: block; margin: auto;" /> ??? - then `geom_point()` adds the dots - ... using the `mapping` (currently referred to as "blah") --- class: middle, inverse background-image: url("img/code.jpg") background-size: cover <img src="img/My_First_Plot4.png" width="500" height="500" style="display: block; margin: auto;" /> ??? - the `mapping` tells R *how* to connect the plot to the data - in this case we map `x` onto the `displ` variable - and we map `y` onto the `hwy` variable --- class: middle, inverse background-image: url("img/code.jpg") background-size: cover <img src="img/My_First_Plot5.png" width="500" height="500" style="display: block; margin: auto;" /> ??? - `displ` is essentially a measure of engine size - `hwy` is fuel efficiency for highway driving --- class: inverse .pull-left[ .hand[the real code ❤️] ```r library(tidyverse) ggplot(data = mpg) + geom_point( mapping = aes( x = displ, y = hwy ) ) ``` ] -- .pull-right[ .hand[... and the real output!] ![](index_files/figure-html/hello-r-output-1.png)<!-- --> ] --- class: middle ## .hand[exercise 1...👯♀️] - how to show the city mileage `cty` as the y-value? - how to show the manufacture `year` as the x-value? - how to show the number of cylinders `cyl` as the colour? - (bonus): how to include a regression line instead of dot points? ??? - they're not expected to know all the answers! - questions 1-3 promote intuitive grasp of mappings - question 4 is there to foreshadow geoms --- class: middle, inverse .hand[i am very good at art] <img src="img/My_First_Plot.gif" width="500" height="500" style="display: block; margin: auto;" /> --- class: middle background-image: url("img/maps_light.jpg") background-size: cover .pull-left-narrow[ .huge-blue-number[2] ] .pull-right-wide[ .larger[ aesthetic<br> mappings<br> 🎨 🗺 ] ] --- class: middle, inverse background-image: url("img/maps.jpg") background-size: cover --- class: middle, inverse background-image: url("img/maps.jpg") background-size: cover <img src="img/Mapping1.png" width="500" height="500" style="display: block; margin: auto;" /> ??? - let's unpack the contents of that "blah", shall we? - the `ggplot(data = mpg)` part tells us the `mpg` data go with our plot --- class: middle, inverse background-image: url("img/maps.jpg") background-size: cover <img src="img/Mapping2.png" width="500" height="500" style="display: block; margin: auto;" /> ??? - the `mpg` data contains "variables" - here are some of those variables in the data... - but how do they "map" to the plot??? --- class: middle, inverse background-image: url("img/maps.jpg") background-size: cover <img src="img/Mapping3.png" width="500" height="500" style="display: block; margin: auto;" /> ??? - the visual content/features of a plot are "aesthetics" - `x` coordinates and `y` coordinates are aesthetics - can include things like `size` and `colour` also - (mention US/UK spelling) --- class: middle, inverse background-image: url("img/maps.jpg") background-size: cover <img src="img/Mapping4.png" width="500" height="500" style="display: block; margin: auto;" /> ??? - that "blah" was an **aesthetic mapping** - it tells R which plot aesthetics are mapped onto which variables in the data --- class: middle, inverse background-image: url("img/maps.jpg") background-size: cover <img src="img/Mapping5.png" width="500" height="500" style="display: block; margin: auto;" /> --- class: middle, inverse background-image: url("img/maps.jpg") background-size: cover <img src="img/Mapping6.png" width="500" height="500" style="display: block; margin: auto;" /> --- class: inverse .pull-left[ .hand[using real code this time...] ```r ggplot(data = mpg) + geom_point( * mapping = aes( * x = displ, * y = hwy * ) ) ``` ] --- class: inverse .pull-left[ .hand[using real code this time...] ```r aes( x = displ, y = hwy ) ``` ] -- .pull-right[ .hand[.] ``` ## Aesthetic mapping: ## * `x` -> `displ` ## * `y` -> `hwy` ``` ] --- class: inverse .pull-left[ .hand[can we add colour to this?] ```r ggplot(data = mpg) + geom_point( mapping = aes( x = displ, y = hwy ) ) ``` ] .pull-right[ .hand[.] ![](index_files/figure-html/hello-r-output-2-1.png)<!-- --> ] ??? - ask them to set colour to the number of cylinders `cyl` - (not a class exercise, just to segue...) --- class: inverse .pull-left[ .hand[add **colour** to the mapping!] ```r ggplot(data = mpg) + geom_point( mapping = aes( x = displ, y = hwy, * color = cyl ) ) ``` ] -- .pull-right[ .hand[...the output gets colour] ![](index_files/figure-html/unnamed-chunk-16-1.png)<!-- --> ] ??? - prompt: is something wrong here? - hint: can you have 5.21 cylinders in an engine? - (don't give them the answer yet...) --- class: middle ## .hand[exercise 2...👩💻] code along with me while we... - look at the `mpg` data - recreate the last plot - change the mapped **variables** (type `mpg` to see variables) - change the mapped **aesthetics** (e.g. `x`, `y`, `color`, `size`, `fill`, `shape`) ??? - do the typing in rstudio cloud and get them to type along - get them to suggest possible code edits... - let them discover the "continuous variable cannot be mapped..." error - talk them through it and show them `factor()` as the answer ```{=html} <div class="countdown" id="timer_606c4660" style="right:0;bottom:0;" data-warnwhen="0"> <code class="countdown-time"><span class="countdown-digits minutes">02</span><span class="countdown-digits colon">:</span><span class="countdown-digits seconds">00</span></code> </div> ``` --- class: middle background-image: url("img/layer-cake_light.jpg") background-size: cover .pull-left-narrow[ .huge-blue-number[3] ] .pull-right-wide[ .larger[ layered<br> plots<br> 🍰 ] ] --- class: middle, inverse background-image: url("img/layer-cake.jpg") background-size: cover --- class: middle, inverse background-image: url("img/layer-cake.jpg") background-size: cover <img src="img/Layers1.png" width="500" height="500" style="display: block; margin: auto;" /> --- class: middle, inverse background-image: url("img/layer-cake.jpg") background-size: cover <img src="img/Layers2.png" width="500" height="500" style="display: block; margin: auto;" /> --- class: middle, inverse background-image: url("img/layer-cake.jpg") background-size: cover <img src="img/Layers3.png" width="500" height="500" style="display: block; margin: auto;" /> --- class: inverse .pull-left[ .hand[our plot has a "points" layer] ```r ggplot(data = mpg) + *geom_point( mapping = aes( x = displ, y = hwy, color = cyl ) ) ``` ] -- .pull-right[ .hand[.] ![](index_files/figure-html/unnamed-chunk-21-1.png)<!-- --> ] --- class: inverse .pull-left[ .hand[adding **geom_smooth()**] ```r ggplot(data = mpg) + geom_point( mapping = aes( x = displ, y = hwy, color = cyl ) ) + *geom_smooth( * mapping = aes( * x = displ, * y = hwy * ) *) ``` ``` ## `geom_smooth()` using method = 'loess' and formula 'y ~ x' ``` ] .pull-right[ .hand[paints another layer] ![](index_files/figure-html/unnamed-chunk-22-1.png)<!-- --> ] --- class: middle ## .hand[exercise 3...👩💻] code along with me while we... - recreate the plot with `geom_point()` only - add the `geom_smooth()` layer - add a third layer with `geom_rug()` --- class: middle background-image: url("img/tidy.jpg") background-size: cover .pull-left-narrow[ .huge-blue-number[4] ] .pull-right-wide[ .larger[ tidy code ] ] --- class: inverse .pull-left[ .hand[hm... this is annoying] ```r ggplot(data = mpg) + geom_point( * mapping = aes( * x = displ, * y = hwy, color = cyl ) ) + geom_smooth( * mapping = aes( * x = displ, * y = hwy ) ) ``` ] -- .pull-right[ .hand[can we eliminate this redundancy?] - `x` and `y` values are the same - make them **global** aesthetics ] --- class: inverse .pull-left[ .hand[we can just move the code!] ```r ggplot(data = mpg, * mapping = aes( * x = displ, * y = hwy * ) ) + geom_point( mapping = aes( color = cyl ) ) + geom_smooth() ``` ] -- .pull-right[ <br> - the `mapping` within the `ggplot()` command is "global" ] --- class: inverse .pull-left[ .hand[we can just move the code!] ```r ggplot(data = mpg, mapping = aes( x = displ, y = hwy ) ) + *geom_point( mapping = aes( color = cyl ) ) + *geom_smooth() ``` ] .pull-right[ <br> - the `mapping` within the `ggplot()` command is "global" - both "geoms" will use the `x` and `y` values that they "inherit" ] --- class: inverse .pull-left[ .hand[we can just move the code!] ```r ggplot(data = mpg, mapping = aes( x = displ, y = hwy ) ) + geom_point( * mapping = aes( * color = cyl * ) ) + geom_smooth() ``` ] .pull-right[ <br> - the `mapping` within the `ggplot()` command is "global" - both "geoms" will use the `x` and `y` values that they "inherit" - the `color` aesthetic remains "local" to `geom_point()` ] --- class: inverse .left[ .hand[same code, just neater!] ```r ggplot( data = mpg, mapping = aes(x = displ, y = hwy) ) + geom_point(mapping = aes(color = cyl)) + geom_smooth() ``` ] --- .left[ .hand[exercise 4... paired discussion 👯♀️] ```r ggplot( data = mpg, mapping = aes(x = displ, y = hwy) ) + geom_point(mapping = aes(color = cyl)) + geom_smooth() ``` ] .left[ - what are the **variables**? - what are the **geoms**, and what do they do? - identify the R **functions** this code uses - why did I say this is the "same" code as before? ] --- class: middle background-image: url("img/dinosaur.jpg") background-size: cover .pull-left-narrow[ .huge-blue-number[5] ] .pull-right-wide[ .larger[ 👯♀️ ] ] --- background-image: url("img/dinosaur.jpg") background-size: cover .pull-left-wide[ .hand[exercise_ggplot_05.R] ```r library(tidyverse) dino <- read_csv("data_dino.csv") picture <- ggplot(data = dino) + geom_point( mapping = aes( x = horizontal, y = vertical ) ) plot(picture) ``` ] -- .pull-right-narrow[ <br><br> ![](index_files/figure-html/unnamed-chunk-23-1.png)<!-- --> ] --- class: middle background-image: url("img/handwriting_light.jpg") background-size: cover .pull-left-narrow[ .huge-blue-number[6] ] .pull-right-wide[ .larger[ naming<br> things<br> ] ] --- class: inverse .pull-left-wide[ .hand[from the exercise] ```r dino <- read_csv("data_dino.csv") *picture <- ggplot(data = dino) + geom_point( mapping = aes( x = horizontal, y = vertical ) ) plot(picture) ``` ] .pull-right-narrow[ <br><br> ![](index_files/figure-html/unnamed-chunk-24-1.png)<!-- --> ] --- class: inverse .pull-left-wide[ .hand[this is the same!] ```r dino <- read_csv("data_dino.csv") *picture <- ggplot(dino) + geom_point( mapping = aes( x = horizontal, y = vertical ) ) plot(picture) ``` ] .pull-right-narrow[ <br><br> ![](index_files/figure-html/unnamed-chunk-25-1.png)<!-- --> ] -- .pull-left-wide[ - named argument: `ggplot(data = dino)` - unnamed argument: `ggplot(dino)` ] --- class: inverse .pull-left-wide[ .hand[unnamed arguments] ```r *dino <- read_csv("data_dino.csv") *picture <- ggplot(dino) + geom_point( mapping = aes( x = horizontal, y = vertical ) ) *plot(picture) ``` ] .pull-right-narrow[ <br><br> ![](index_files/figure-html/unnamed-chunk-26-1.png)<!-- --> ] --- class: inverse .pull-left-wide[ .hand[named argument] ```r dino <- read_csv("data_dino.csv") picture <- ggplot(dino) + geom_point( * mapping = aes( x = horizontal, y = vertical ) ) plot(picture) ``` ] .pull-right-narrow[ <br><br> ![](index_files/figure-html/unnamed-chunk-27-1.png)<!-- --> ] --- class: inverse .pull-left-wide[ .hand[unnamed] ```r dino <- read_csv("data_dino.csv") picture <- ggplot(dino) + geom_point( * aes( x = horizontal, y = vertical ) ) plot(picture) ``` ] .pull-right-narrow[ <br><br> ![](index_files/figure-html/unnamed-chunk-28-1.png)<!-- --> ] --- class: inverse .pull-left-wide[ .hand[one more time!] ```r dino <- read_csv("data_dino.csv") picture <- ggplot(dino) + geom_point( aes( * x = horizontal, * y = vertical ) ) plot(picture) ``` ] .pull-right-narrow[ <br><br> ![](index_files/figure-html/unnamed-chunk-29-1.png)<!-- --> ] --- class: inverse .pull-left-wide[ .hand[one more time!] ```r dino <- read_csv("data_dino.csv") picture <- ggplot(dino) + geom_point( aes( * horizontal, * vertical ) ) plot(picture) ``` ] .pull-right-narrow[ <br><br> ![](index_files/figure-html/unnamed-chunk-30-1.png)<!-- --> ] --- class: inverse .pull-left-wide[ .hand[one more time!] ```r dino <- read_csv("data_dino.csv") picture <- ggplot(dino) + * geom_point(aes(horizontal, vertical)) plot(picture) ``` ] .pull-right-narrow[ <br><br> ![](index_files/figure-html/unnamed-chunk-31-1.png)<!-- --> ] --- class: inverse .pull-left-wide[ .hand[ggplot2 code often looks like this!] ```r dino <- read_csv("data_dino.csv") *picture <- ggplot(dino) + * geom_point(aes(horizontal, vertical)) plot(picture) ``` ] .pull-right-narrow[ <br><br> ![](index_files/figure-html/unnamed-chunk-32-1.png)<!-- --> ] --- class: middle background-image: url("img/exercise.jpg") background-size: cover .pull-left-narrow[ .huge-blue-number[7] ] .pull-right-wide[ .larger[ 🏊 ] ] --- class: middle .hand[exercises 6-8... emoji translation!] <img src="img/Exercise04.png" width="600" /> --- class: middle .hand[exercises 9-10... forensic handwriting expertise] .pull-left[ <img src="img/handwriting.jpg" width="600" /> ] .pull-right[ - Martire, Growns & Navarro (2018) *What do the experts know? Calibration, precision, and the wisdom of crowds among forensic handwriting experts* - https://psyarxiv.com/pq7kz ] --- class: middle .hand[exercise 9 plot] <img src="index_files/figure-html/exercise9-1.png" width="600" height="400" /> --- .pull-left[ .hand[exercise 10 solution] ```r ggplot(data = forensic) + geom_boxplot( mapping = aes( x = band, y = est ) ) ``` ] .pull-right[ <br><br> ![](index_files/figure-html/unnamed-chunk-36-1.png)<!-- --> ] --- .pull-left[ .hand[exercise 10 solution] ```r ggplot(data = forensic) + * geom_violin( mapping = aes( x = band, y = est ) ) ``` ] .pull-right[ <br><br> ![](index_files/figure-html/unnamed-chunk-37-1.png)<!-- --> ] --- class: middle background-image: url("img/facets.jpg") background-size: cover .pull-left-narrow[ .huge-blue-number[8] ] .pull-right-wide[ .larger[ facets <br> 🔲 🔲<br> 🔲 🔲<br> ] ] --- class: inverse .hand[split experts and novices?] ```r ggplot(forensic) + geom_boxplot(aes(x = band, y = est)) ``` <img src="index_files/figure-html/facet0-1.png" height="300" /> --- class: inverse .hand[split experts and novices?] ```r ggplot(forensic) + geom_boxplot(aes(x = band, y = est)) + * facet_wrap(vars(handwriting_expert)) ``` <img src="index_files/figure-html/facet1-1.png" width="600" height="300" /> --- class: middle background-image: url("img/one_art_please.png") background-size: cover .pull-left-narrow[ .huge-blue-number[9] ] .pull-right-wide[ .larger[ <span style="color:white;font-weight: bold">glamour</span><br> <span style="color:white;font-weight: bold">graphics</span> ] ] --- class: inverse <blockquote class="twitter-tweet tw-align-center"><p lang="en" dir="ltr">The recording of my <a href="https://twitter.com/hashtag/rstudioconf?src=hash&ref_src=twsrc%5Etfw">#rstudioconf</a> talk, The Glamour of Graphics is up! 💅 Enjoy, and keep in mind these are guidelines, not rules. <a href="https://twitter.com/hashtag/rstats?src=hash&ref_src=twsrc%5Etfw">#rstats</a> <a href="https://t.co/VHz05yAs09">https://t.co/VHz05yAs09</a></p>— Will Chase (@W_R_Chase) <a href="https://twitter.com/W_R_Chase/status/1228683209422057479?ref_src=twsrc%5Etfw">February 15, 2020</a></blockquote> . --- .pull-left[ ```r pic <- ggplot( data = forensic ) + geom_boxplot( mapping = aes( x = band, y = est, fill = band ) ) + facet_wrap( vars(handwriting_expert) ) plot(pic) ``` ] -- .pull-right[ <img src="index_files/figure-html/unnamed-chunk-38-1.png" width="600" height="300" /> ] --- .pull-left[ ```r pic + theme_minimal() ``` ] .pull-right[ <img src="index_files/figure-html/unnamed-chunk-39-1.png" width="600" height="300" /> ] --- .pull-left[ ```r pic + theme_minimal() + scale_x_discrete( name = NULL, labels = NULL ) ``` ] .pull-right[ <img src="index_files/figure-html/unnamed-chunk-40-1.png" width="600" height="300" /> ] --- .pull-left[ ```r pic <- pic + theme_minimal() + scale_x_discrete( name = NULL, labels = NULL ) + scale_y_continuous( name = NULL ) pic ``` ] .pull-right[ <img src="index_files/figure-html/unnamed-chunk-41-1.png" width="600" height="300" /> ] --- .pull-left[ ```r pic <- pic + ggtitle( "Estimated frequency of handwriting features" ) pic ``` ] .pull-right[ <img src="index_files/figure-html/unnamed-chunk-42-1.png" width="600" height="300" /> ] --- .pull-left[ ```r pic + scale_fill_viridis_d() ``` ] .pull-right[ <img src="index_files/figure-html/unnamed-chunk-43-1.png" width="600" height="300" /> ] --- .pull-left[ ```r pic + scale_fill_viridis_d( alpha = .5 ) ``` ] .pull-right[ <img src="index_files/figure-html/unnamed-chunk-44-1.png" width="600" height="300" /> ] --- .pull-left[ ```r pic + scale_fill_viridis_d( alpha = .5, name = NULL ) ``` ] .pull-right[ <img src="index_files/figure-html/unnamed-chunk-45-1.png" width="600" height="300" /> ] --- <img src="index_files/figure-html/unnamed-chunk-46-1.png" style="display: block; margin: auto;" /> --- <img src="index_files/figure-html/style8-1.png" style="display: block; margin: auto;" /> --- .hand[So now you know the basics. Where to next?] *Refresher?* ...try this lovely tutorial! <br> https://ggplot2tutor.com/viz-pages/beginner_tutorial/beginner_tutorial/ *A classic?* ...look into "R for Data Science" <br> https://r4ds.had.co.nz/data-visualisation.html *This but extra?* ...I wrote an advanced workshop<br> https://djnavarro.github.io/satrdayjoburg/ *A full book?* ...Keiran Healy's book is very good! <br> https://socviz.co/