layout: true <!-- this adds the link footer to all slides, depends on footer-small class in css--> <div class="footer-small"><span>https://github.com/mjfrigaard/csuc-data-journalism</div> --- name: title-slide class: title-slide, center, middle, inverse # Data Visualization with ggplot2 (part 1) #.fancy[An introduction to the grammar of graphics] <br> .large[by Martin Frigaard] Written: September 21 2021 Updated: November 30 2021 .footer-large[.right[.fira[ <br><br><br><br><br>[Created using the "λέξις" theme](https://jhelvy.github.io/lexis/index.html#what-does-%CE%BB%CE%AD%CE%BE%CE%B9%CF%82-mean) ]]] --- <img src="img/ggplot2_masterpiece.png" width="65%" height="65%" style="display: block; margin: auto;" /> .footer-large[.right[Art by Allison Horst]] --- class: inverse, center background-image: url(img/ggplot2.png) background-position: 50% 70% background-size: 30% # Intro to Data Visualization with R with `ggplot2` (part 1) --- class: left, top background-image: url(img/ggplot2.png) background-position: 93% 7% background-size: 6% # Objectives ## 1) Introduce the grammar of graphics ## 2) Identifying graph aesthetics ## 3) Recognizing and using `geoms` ## 4) Faceting graphs --- class: left, top background-image: url(img/ggplot2.png) background-position: 93% 7% background-size: 6% # Resources ## Link to slides https://mjfrigaard.github.io/csuc-data-journalism/slides.html ## Link to exercises https://mjfrigaard.github.io/csuc-data-journalism/lessons.html --- class: left, top background-image: url(img/ggplot2.png) background-position: 93% 7% background-size: 6% # Why use `ggplot2` for data visualization? <br> -- ### 1) `ggplot2` provides a comprehensive grammar for creating graphs/figures -- ### 2) It works hand-and-hand with the `tidyverse` -- ### 3) Better plots = better communication --- class: left, top background-image: url(img/ggplot2.png) background-position: 93% 7% background-size: 6% # Why do we create data visualizations? ## Exploration and Clarification .large[ > "The simple graph has brought more information to the data analyst’s mind than any other device." - John Tukey ] --- class: left, top background-image: url(img/ggplot2.png) background-position: 93% 7% background-size: 6% # Why do we create data visualizations? ## Better decision making .large[ > "Data visualization is a collection of methods that use visual representations to explore, make sense of, and communicate quantitative data... the ultimate purpose of data visualization, beyond understanding, is to enable better decisions and actions." - Stephen Few ] --- class: left, top background-image: url(img/ggplot2.png) background-position: 95% 7% background-size: 6% # How should we start creating data visualizations? -- ## Start with pen and paper -- ### *get those first (bad) ideas out of the way* -- ## Import and inspect your data -- ### *so you know what to expect* --- background-image: url(img/ggplot2.png) background-position: 96% 8% background-size: 6% ## Layered grammar of graphics -- > *"appreciating the engineering design behind a sentence – **a linear ordering of phrases which conveys a gnarly network of ideas** — is the key to understanding what you are trying to accomplish when you compose a sentence."* - Stephen Pinker -- > *"language is a system for making infinite use of finite means."* - Wilhelm von Humboldt -- ### `ggplot2` is a **language of layers, organized linearly** -- The layers give us a "*linear ordering of phrases*" to build an infinite number of graphs ("*which convey a gnarly network of ideas.*") ### ...infinitely extensible --- background-image: url(img/ggplot2.png) background-position: 96% 8% background-size: 6% ### Let's load some data! The `NHANES` package comes with data from the [2014 American National Health and Nutrition Examination surveys](http://www.cdc.gov/nchs/data/series/sr_02/sr02_162.pdf). We will load a sample from it below: ```r SmallNhanes <- read_csv("https://bit.ly/nhanes-small") head(SmallNhanes) ``` <div data-pagedtable="false"> <script data-pagedtable-source type="application/json"> {"columns":[{"label":["ID"],"name":[1],"type":["dbl"],"align":["right"]},{"label":["Gender"],"name":[2],"type":["chr"],"align":["left"]},{"label":["Age"],"name":[3],"type":["dbl"],"align":["right"]},{"label":["AgeDecade"],"name":[4],"type":["chr"],"align":["left"]},{"label":["Race1"],"name":[5],"type":["chr"],"align":["left"]},{"label":["HealthGen"],"name":[6],"type":["chr"],"align":["left"]},{"label":["Height"],"name":[7],"type":["dbl"],"align":["right"]},{"label":["BMI"],"name":[8],"type":["dbl"],"align":["right"]},{"label":["Weight"],"name":[9],"type":["dbl"],"align":["right"]},{"label":["Pulse"],"name":[10],"type":["dbl"],"align":["right"]},{"label":["BPSysAve"],"name":[11],"type":["dbl"],"align":["right"]}],"data":[{"1":"51624","2":"male","3":"34","4":"30-39","5":"White","6":"Good","7":"164.7","8":"32.22","9":"87.4","10":"70","11":"113"},{"1":"51624","2":"male","3":"34","4":"30-39","5":"White","6":"Good","7":"164.7","8":"32.22","9":"87.4","10":"70","11":"113"},{"1":"51624","2":"male","3":"34","4":"30-39","5":"White","6":"Good","7":"164.7","8":"32.22","9":"87.4","10":"70","11":"113"},{"1":"51625","2":"male","3":"4","4":"0-9","5":"Other","6":"NA","7":"105.4","8":"15.30","9":"17.0","10":"NA","11":"NA"},{"1":"51630","2":"female","3":"49","4":"40-49","5":"White","6":"Good","7":"168.4","8":"30.57","9":"86.7","10":"86","11":"112"},{"1":"51638","2":"male","3":"9","4":"0-9","5":"White","6":"NA","7":"133.1","8":"16.82","9":"29.8","10":"82","11":"86"}],"options":{"columns":{"min":{},"max":[10]},"rows":{"min":[10],"max":[10]},"pages":{}}} </script> </div> --- background-image: url(img/ggplot2.png) background-position: 95% 8% background-size: 6% ### Quick Tip: Column Names **Standardize names** ```r SmallNhanes <- SmallNhanes %>% janitor::clean_names() head(SmallNhanes) ``` <div data-pagedtable="false"> <script data-pagedtable-source type="application/json"> {"columns":[{"label":["id"],"name":[1],"type":["dbl"],"align":["right"]},{"label":["gender"],"name":[2],"type":["chr"],"align":["left"]},{"label":["age"],"name":[3],"type":["dbl"],"align":["right"]},{"label":["age_decade"],"name":[4],"type":["chr"],"align":["left"]},{"label":["race1"],"name":[5],"type":["chr"],"align":["left"]},{"label":["health_gen"],"name":[6],"type":["chr"],"align":["left"]},{"label":["height"],"name":[7],"type":["dbl"],"align":["right"]},{"label":["bmi"],"name":[8],"type":["dbl"],"align":["right"]},{"label":["weight"],"name":[9],"type":["dbl"],"align":["right"]},{"label":["pulse"],"name":[10],"type":["dbl"],"align":["right"]},{"label":["bp_sys_ave"],"name":[11],"type":["dbl"],"align":["right"]}],"data":[{"1":"51624","2":"male","3":"34","4":"30-39","5":"White","6":"Good","7":"164.7","8":"32.22","9":"87.4","10":"70","11":"113"},{"1":"51624","2":"male","3":"34","4":"30-39","5":"White","6":"Good","7":"164.7","8":"32.22","9":"87.4","10":"70","11":"113"},{"1":"51624","2":"male","3":"34","4":"30-39","5":"White","6":"Good","7":"164.7","8":"32.22","9":"87.4","10":"70","11":"113"},{"1":"51625","2":"male","3":"4","4":"0-9","5":"Other","6":"NA","7":"105.4","8":"15.30","9":"17.0","10":"NA","11":"NA"},{"1":"51630","2":"female","3":"49","4":"40-49","5":"White","6":"Good","7":"168.4","8":"30.57","9":"86.7","10":"86","11":"112"},{"1":"51638","2":"male","3":"9","4":"0-9","5":"White","6":"NA","7":"133.1","8":"16.82","9":"29.8","10":"82","11":"86"}],"options":{"columns":{"min":{},"max":[10]},"rows":{"min":[10],"max":[10]},"pages":{}}} </script> </div> --- background-image: url(img/ggplot2.png) background-position: 95% 20% background-size: 6% ### Quick Tip: Factors **Format factors:** We have a `health_gen` variable with the following levels: `Excellent`, `Vgood`, `Good`, `Fair`, or `Poor`. These are ordered. -- ```r SmallNhanes <- SmallNhanes %>% mutate( health_gen = factor(x = health_gen, levels = c("Poor", "Fair", "Good", "Vgood", "Excellent"), ordered = TRUE)) ``` -- ```r levels(SmallNhanes$health_gen) ``` ``` [1] "Poor" "Fair" "Good" "Vgood" "Excellent" ``` --- background-image: url(img/ggplot2.png) background-position: 96% 8% background-size: 6% ## Layered grammar of graphics ## How it works: -- #### 1) Graphs are *initialized* with *ggplot()* -- #### 2) Variables are *mapped* to *aesthetics* -- #### 3) Geoms are linked to *statistics* --- background-image: url(img/ggplot2.png) background-position: 96% 8% background-size: 6% # Our First Graph <br><br><br> ## *What relationship do you expect to see between `height` and `weight`*? --- background-image: url(img/ggplot2.png) background-position: 95% 90% background-size: 6% ## 1. Use data with pipe to initialize graph `SmallNhanes %>%` -- ## 2. Map variables to aesthetics `SmallNhanes %>%` `ggplot(mapping = aes(x = weight, y = height))` -- ## 3. Add geoms and layers `SmallNhanes %>% ` `ggplot(mapping = aes(x = weight, y = height)) +` `geom_point()` --- background-image: url(img/ggplot2.png) background-position: 95% 90% background-size: 6% .border[ ```r SmallNhanes %>% * ggplot() # initialize ``` <img src="img/initialize-1.png" width="80%" height="80%" style="display: block; margin: auto;" /> ] --- background-image: url(img/ggplot2.png) background-position: 95% 90% background-size: 5% .border[ ```r SmallNhanes %>% * ggplot(mapping = aes(x = weight, y = height)) # map variables ``` <img src="img/mapping-1.png" width="80%" height="80%" style="display: block; margin: auto;" /> ] --- background-image: url(img/ggplot2.png) background-position: 95% 90% background-size: 6% .border[ ```r SmallNhanes %>% ggplot(mapping = aes(x = weight, y = height)) + * geom_point() # add geoms ``` <img src="img/geoms-1.png" width="80%" height="80%" style="display: block; margin: auto;" /> ] --- background-image: url(img/ggplot2.png) background-position: 95% 7% background-size: 6% # `ggplot2` template #### Initialize the plot the `ggplot()`, map the aesthetics, and add a `<GEOM_FUNCTION>` ```r <DATA> %>% ggplot(mapping = aes(<MAPPINGS>)) + <GEOM_FUNCTION>() ``` -- #### We can add more aesthetics *inside* geoms ```r <DATA> %>% ggplot(mapping = aes(<MAPPINGS>)) + * <GEOM_FUNCTION>(mapping = aes(<MAPPINGS>)) ``` --- background-image: url(img/ggplot2.png) background-position: 95% 7% background-size: 6% # `ggplot2` template #### Because `ggplot2` is a language of layers, we can continue adding *more* geoms ```r <DATA> %>% ggplot(mapping = aes(<MAPPINGS>)) + * <GEOM_FUNCTION>(mapping = aes(<MAPPINGS>)) + * <GEOM_FUNCTION>(mapping = aes(<MAPPINGS>)) ``` #### Note the different syntax (.red[%>%] vs. .red[+]) ```r <DATA> %>% #<< pipe! ggplot(mapping = aes(<MAPPINGS>)) + #<< plus! <GEOM_FUNCTION>(mapping = aes(<MAPPINGS>)) ``` --- class: inverse, center background-image: url(img/ggplot2.png) background-position: 50% 60% background-size: 30% # Graph Aesthetics --- background-image: url(img/ggplot2.png) background-position: 95% 7% background-size: 7% # Aesthetics #### Is the relationship between `weight` and `height` the same for both `gender`s? *We can explore this by mapping the variables to different aesthetics* -- #### Aesthetics as graph elements (`color`, `size`, `shape`, and `alpha`) .border[ <img src="img/graph-elements.png" width="80%" height="80%" style="display: block; margin: auto;" /> ] --- class: inverse, center background-image: url(img/ggplot2.png) background-position: 50% 60% background-size: 30% # Mapping (global vs. local) --- background-image: url(img/ggplot2.png) background-position: 95% 7% background-size: 7% # Global `ggplot2` mapping ### ***inside the `ggplot()` function*** = setting variables ***globally*** <img src="img/ggplot2-template-01.png" width="90%" height="90%" /> --- background-image: url(img/ggplot2.png) background-position: 95% 7% background-size: 7% # Local `ggplot2` mapping ### ***inside the `geom()` function*** = setting variables ***locally*** <img src="img/ggplot2-template-02.png" width="85%" height="85%" /> --- background-image: url(img/ggplot2.png) background-position: 95% 7% background-size: 6% ## Your Turn ### Set local vs. global aesthetic mappings .leftcol[ *From here...* ```r SmallNhanes %>% ggplot( * mapping = * aes(x = weight, y = height)) + geom_point() + geom_smooth() ``` ] -- .rightcol[ *...to here.* ```r SmallNhanes %>% ggplot() + geom_point( * mapping = * aes(x = weight, y = height)) + geom_smooth( * mapping = * aes(x = weight, y = height)) ``` ] --- background-image: url(img/ggplot2.png) background-position: 95% 7% background-size: 6% ### Your Turn (solution 1) .border[ ```r SmallNhanes %>% * ggplot(mapping = aes(x = weight, y = height)) + geom_point() + geom_smooth() ``` <img src="img/aes-in-ggplot2-sol-1.png" width="60%" height="60%" style="display: block; margin: auto;" /> ] --- background-image: url(img/ggplot2.png) background-position: 95% 7% background-size: 6% ### Your Turn (solution 2) .border[ ```r SmallNhanes %>% ggplot() + * geom_point(mapping = aes(x = weight, y = height)) + * geom_smooth(mapping = aes(x = weight, y = height)) ``` <img src="img/aes-in-geom-sol-1.png" width="60%" height="60%" style="display: block; margin: auto;" /> ] --- class: inverse, center background-image: url(img/ggplot2.png) background-position: 50% 60% background-size: 30% # Variables, Aestheitcs, and Geoms --- background-image: url(img/ggplot2.png) background-position: 95% 7% background-size: 6% ### Variables, Aestheitcs, and Geoms (1) Each graph needs a variable or value, an aesthetic, and geom (the accompanying graphic, geometry) -- ```r *geom_point(mapping = aes(x = weight, y = height)) + # layer 1 *geom_smooth(mapping = aes(x = weight, y = height)) # layer 2 ``` -- | variable | aesthetic | geom | |:---------:|:-------------:|:----------------:| | `weight` | position = `x`| dots = `point` | | `height` | position = `y`| dots = `point` | | `weight` | position = `x`| line = `smooth` | | `height` | position = `y`| line = `smooth` | -- These have the same aesthetics! What if we added a layer with a variable mapped to a different aesthetic? --- background-image: url(img/ggplot2.png) background-position: 95% 7% background-size: 6% ### Variables, Aestheitcs, and Geoms (2) But we can add *more* variables, map them to *different* aesthetics, and *adding* another `geom` layer -- Add another layer, coloring the points by `gender` ```r SmallNhanes %>% ggplot() + * geom_point(mapping = aes(x = weight, y = height)) + * geom_point(mapping = aes(color = gender)) ``` -- | variable | aesthetic | geom | |:---------:|:--------------:|:----------------:| | `weight` | position = `x` | dots = `point` | | `height` | position = `y` | dots = `point` | | `gender` | color = `color`| dots = `point` | --- background-image: url(img/ggplot2.png) background-position: 95% 7% background-size: 6% ### Variables, Aestheitcs, and Geoms (3) .leftcol55[ #### ERROR! ```r SmallNhanes %>% ggplot() + geom_point( * aes(x = weight, y = height)) + geom_point( * aes(color = gender)) ``` ```r # Error: geom_point requires the following missing aesthetics: x and y ``` ] .rightcol45[ #### SOLUTION All `geom`s have required aesthetics--map variables globally ```r SmallNhanes %>% ggplot( * aes(x = weight, y = height)) + * geom_point(aes(color = gender)) ``` ] --- background-image: url(img/ggplot2.png) background-position: 95% 90% background-size: 4% ### Aesthetics: color .border[ ```r SmallNhanes %>% ggplot(aes(x = weight, y = height)) + * geom_point(aes(color = gender)) ``` <img src="img/color-1.png" width="60%" height="60%" style="display: block; margin: auto;" /> ] --- background-image: url(img/ggplot2.png) background-position: 95% 90% background-size: 4% ### Aesthetics: size .border[ ```r SmallNhanes %>% ggplot(aes(x = weight, y = height)) + * geom_point(aes(color = gender, size = gender)) ``` <img src="img/size-point-1.png" width="60%" height="60%" style="display: block; margin: auto;" /> ] --- background-image: url(img/ggplot2.png) background-position: 95% 90% background-size: 4% ### Aesthetics: shape .border[ ```r SmallNhanes %>% ggplot(aes(x = weight, y = height)) + * geom_point(aes(color = gender, size = gender, shape = gender)) ``` <img src="img/shape-point-1.png" width="60%" height="60%" style="display: block; margin: auto;" /> ] --- background-image: url(img/ggplot2.png) background-position: 95% 90% background-size: 4% ### Aesthetics: alpha (opacity) .border[ ```r SmallNhanes %>% ggplot(aes(x = weight, y = height)) + * geom_point(aes(color = gender, alpha = gender)) ``` <img src="img/alpha-point-1.png" width="60%" height="60%" style="display: block; margin: auto;" /> ] --- background-image: url(img/ggplot2.png) background-position: 95% 90% background-size: 4% # Aesthetic mappings -- .pull-left[ #### Legend is automatically included #### Continuous variables best with `size` ] -- .pull-right[.border[ <img src="img/aes-settings.png" width="100%" height="100%" style="display: block; margin: auto;" /> ]] --- background-image: url(img/ggplot2.png) background-position: 95% 90% background-size: 4% ## Setting values vs. mapping variables ### How can we create this plot? .border[ <img src="img/red-points-1-1.png" width="70%" height="70%" style="display: block; margin: auto;" /> ] --- background-image: url(img/ggplot2.png) background-position: 95% 90% background-size: 4% ### Inside `aes()` .border[ ```r SmallNhanes %>% ggplot(aes(x = weight, y = height)) + * geom_point(aes(color = "red")) # inside aes ``` <img src="img/inside-aes-no-eval-1.png" width="65%" height="65%" style="display: block; margin: auto;" /> ] --- background-image: url(img/ggplot2.png) background-position: 95% 90% background-size: 4% ### Outside `aes()` .border[ ```r SmallNhanes %>% ggplot(aes(x = weight, y = height)) + * geom_point(color = "red") # outside aes ``` <img src="img/red-points-1.png" width="65%" height="65%" style="display: block; margin: auto;" /> ] --- background-image: url(img/ggplot2.png) background-position: 95% 90% background-size: 4% ## What happened? `aes()` expected a variable, not a value (`"red"`). ```r SmallNhanes %>% ggplot(aes(x = weight, y = height)) + * geom_point(aes(color = "red")) # "value" in aes ``` -- .border[ <img src="img/inside-aes-no-eval-2-1.png" width="50%" height="50%" style="display: block; margin: auto;" /> ] --- class: inverse, center background-image: url(img/ggplot2.png) background-position: 50% 60% background-size: 30% # Geoms (geometric objects) --- background-image: url(img/ggplot2.png) background-position: 95% 90% background-size: 6% ## Geoms -- ### These are visual elements used to represent the data of the graph -- ### Examples include: - `geom_boxplot` - `geom_col` - `geom_line` - `geom_smooth` -- ### See the cheatsheet for more examples: https://bit.ly/ggplot2-cheat --- background-image: url(img/ggplot2.png) background-position: 95% 7% background-size: 6% ## Your Turn -- ### *How does BMI vary across levels of self-reported general health?* -- ### Complete the code below: Map the variables locally inside the `geom_boxplot()` function ```r SmallNhanes %>% ggplot() %>% geom_boxplot(mapping = aes(x = __________, y = ___)) ``` --- background-image: url(img/ggplot2.png) background-position: 95% 90% background-size: 4% ```r SmallNhanes %>% ggplot() + * geom_boxplot(mapping = aes(x = health_gen, y = bmi)) ``` -- #### Box-plots are great for seeing how a continuous variable varies across a categorical variable .border[ <img src="img/box-plot-show-1-1.png" width="60%" height="60%" style="display: block; margin: auto;" /> ] --- background-image: url(img/ggplot2.png) background-position: 95% 7% background-size: 6% ## Your Turn <br> -- ### Fill in the code below to change the colors in the boxplot for each level of `health_gen` ```r SmallNhanes %>% ggplot() + geom_boxplot( * aes(x = health_gen, y = bmi, _____ = health_gen)) ``` --- background-image: url(img/ggplot2.png) background-position: 95% 90% background-size: 4% ```r SmallNhanes %>% ggplot() + geom_boxplot( * aes(x = health_gen, y = bmi, color = health_gen)) ``` -- .border[ *Color is not the setting we want here...* <img src="img/box-plot-color-1-1.png" width="60%" height="60%" style="display: block; margin: auto;" /> ] --- background-image: url(img/ggplot2.png) background-position: 95% 90% background-size: 4% ```r SmallNhanes %>% ggplot() + geom_boxplot( * aes(x = health_gen, y = bmi, fill = health_gen)) ``` -- .border[ *Fill is better* <img src="img/box-plot-fill-1-1.png" width="60%" height="60%" style="display: block; margin: auto;" /> ] --- background-image: url(img/ggplot2.png) background-position: 95% 7% background-size: 6% # Adding layers -- ### The 'infinitely extensible' part of `ggplot2` is where we start to really see it's power -- ### Consider the relationship between `height` and `weight` again --- background-image: url(img/ggplot2.png) background-position: 95% 90% background-size: 7% ```r SmallNhanes %>% * ggplot(aes(x = weight, y = height)) + # global geom_point(aes(color = gender)) ``` -- .border[ <img src="img/layer-1-plot-1-1.png" width="70%" height="70%" style="display: block; margin: auto;" /> ] --- background-image: url(img/ggplot2.png) background-position: 95% 90% background-size: 7% ```r SmallNhanes %>% ggplot(aes(x = weight, y = height)) + geom_point(aes(color = gender)) + * geom_smooth(data = # data 2 * filter(SmallNhanes, gender == "male"), # layer 2 aes(x = weight, y = height), color = "blue") ``` -- .border[ <img src="img/layer-2-plot-1-1.png" width="64%" height="64%" style="display: block; margin: auto;" /> ] --- background-image: url(img/ggplot2.png) background-position: 95% 90% background-size: 7% ```r SmallNhanes %>% ggplot(aes(x = weight, y = height)) + geom_point(aes(color = gender)) + geom_smooth(data = filter(SmallNhanes, gender == "male"), aes(x = weight, y = height), color = "blue") + * geom_smooth(data = # data 3 * filter(SmallNhanes, gender == "female"), # layer 3 aes(x = weight, y = height), color = "red") ``` -- .border[ <img src="img/layer-3-plot-1-1.png" width="48%" height="18%" style="display: block; margin: auto;" /> ] --- class: inverse, center background-image: url(img/ggplot2.png) background-position: 50% 60% background-size: 30% # Facets --- background-image: url(img/ggplot2.png) background-position: 95% 7% background-size: 9% ## Faceting ### Facet layers display subplots for levels of categorical variables <br> | Facet layer | Display | |:-----------------------------|:-------------------------------------------| | `facet_wrap(. ~ gender)` | Plot for each level of `gender` | | `facet_wrap(race1 ~ gender)` | Plot for each level of `gender` and `race` | | `facet_wrap(. ~ gender, ncol = 1)` | Specify the number of columns | | `facet_wrap(. ~ gender, nrow = 1)` | Specify the number of rows | --- background-image: url(img/ggplot2.png) background-position: 95% 7% background-size: 9% ## Facet Single Variable ```r SmallNhanes %>% ggplot(aes(x = weight, y = height)) + geom_point(aes(color = gender)) + * facet_wrap(. ~ gender) ``` .border[ <img src="img/facet_wrap-1-1.png" width="52%" height="35%" style="display: block; margin: auto;" /> ] --- background-image: url(img/ggplot2.png) background-position: 95% 7% background-size: 9% ## Facet Two Variables ```r SmallNhanes %>% ggplot(aes(x = weight, y = height)) + geom_point(aes(color = gender)) + * facet_wrap(race1 ~ gender) ``` .border[ <img src="img/facet_wrap-2vars-1-1.png" width="52%" height="42%" style="display: block; margin: auto;" /> ] --- background-image: url(img/ggplot2.png) background-position: 95% 7% background-size: 9% ## Facet: Set Columns ```r SmallNhanes %>% ggplot(aes(x = weight, y = height)) + geom_point(aes(color = gender)) + * facet_wrap(race1 ~ gender, ncol = 5) ``` .border[ <img src="img/facet_wrap-cols-1-1.png" width="52%" height="42%" style="display: block; margin: auto;" /> ] --- background-image: url(img/ggplot2.png) background-position: 95% 7% background-size: 9% ## Facet: Set Rows ```r SmallNhanes %>% ggplot(aes(x = weight, y = height)) + geom_point(aes(color = gender)) + * facet_wrap(race1 ~ gender, nrow = 2) ``` .border[ <img src="img/facet_wrap-rows-1-1.png" width="52%" height="42%" style="display: block; margin: auto;" /> ] --- class: left, top background-image: url(img/ggplot2.png) background-position: 93% 7% background-size: 6% # Recap #### 1) Introduction the grammar of graphics syntax #### 2) Identifying graph aesthetics (position, color, shape, opacity, etc.) #### 3) Recognizing and using `geoms` (`geom_point`, `geom_smooth`, etc.) #### 4) Facetting graphs (`facet_wrap` with 1 or two variables) --- background-image: url(img/ggplot2.png) background-position: 95% 7% background-size: 12% # More resources #### The [`ggplot2` book](https://ggplot2-book.org/) #### [`ggplot2`](https://ggplot2.tidyverse.org/) on the tidyverse website #### [Flowing Data](https://flowingdata.com/)