---
title: "Plotting with ggplot2"
author: "Rian DeFaccio, for BH Analytics LLC"
date: "`r Sys.Date()`"
output: 
  html_document:
    toc: true
    toc_depth: 3
    self_contained: yes
    mode: selfcontained
---

```{r setup, include=FALSE}
knitr::opts_knit$set(warning = FALSE, message = FALSE)
knitr::opts_chunk$set(warning = FALSE, message = FALSE)
```

```{r}
# load libraries and adjust settings
library(tidyverse)
library(ggthemes)
```

## Overview

------------------------------------------------------------------------

The next Tidyverse package we will explore, and the most popular graphing package for R, is `ggplot2`.

## Gapminder Data

------------------------------------------------------------------------

This notebook uses the gapminder data. This is an interesting data set containing life expectancy, GDP, and population for all countries on the planet in 5 year increments from 1952 to 2007. You can learn more about the data at the gapminder website:

🌐 <https://www.gapminder.org/data/>

```{r}
df_gapminder <- read.csv('../data/gapminder.csv')

# create a subset of data for just the year 2007
df_2007 <- df_gapminder %>%
  filter(year == 2007 & continent != 'Oceania')
head(df_2007)
```

## The Grammar of Graphics

------------------------------------------------------------------------

It is built on the idea of the "Grammar of Graphics", which is described as follows by Hadley Wickham, the creator of ggplot2:

> "There is a grammar to the composition of graphical components in statistical graphics, and by directly controlling that grammar, you can generate a large set of carefully constructed graphics tailored to your particular needs"
>
> \- Hadley Wickham

See the book **ggplot2: Elegant Graphics for Data Analysis** for an in-depth treatment on the grammar of graphics and how it is implemented in ggplot2.

🌐 <https://ggplot2-book.org/>

In short, our plots are made up of the following components:

-   **Data:** This seems obvious, but without data, we don't have a plot.
-   **Aesthetics:** We map certain variables to certain aesthetics, such as x- or y-position, color, line types, etc.
-   **Geometries:** We have 0-dimensional (points), 1-D (lines), usually up to 2-D (areas like bars, or space under a density plot) representations of our data on the plot.
-   **Statistics:** We don't always calculate statistics from the data, but showing a linear trend line is an example of this element.
-   **Scales:** We don't often think about the scale, but an example where you might is when changing an x- or y-axis onto a log scale.
-   **Coordinates:** We also often overlook the coordinate system we are using, since it is typically a 2-D Cartesian system. However, this is something you can change, such as when using polar coordinates.
-   **Facets:** We use facets to break up our data into subsets to display separately.

We then use these elements and start adding layers onto our plots. We can have many layers, and in each layer you may alter many of the above elements. Most of the ggplot2 functions have names that more-or-less align with these definitions of the plotting elements.

We will not go into great detail on all these elements here today, but will highlight the ones that we typically find most important in daily work.

## Geometries and Aesthetics

------------------------------------------------------------------------

Let's now use ggplot2 for graphics instead of base R. Lets rebuild the previous scatter plot using ggplot2.

The first step is to call the `ggplot()` function.

1.  The first argument is always the data set we are using to build the plot.
2.  The second argument is a call to the `aes()` function. Here the `aes` is referencing *aesthetics* which are attributes of the plot that are mapped to a variable in the data. We can reference columns names directly here, just like we did when using `with()` in our base R plots.
3.  We then define the *geometries*, or elements of the plot that illustrate the data. We add specifications to our plot with separate functions separated by a `+` operator. Functions that define geometries all start with `geom_`.

```{r}
ggplot(df_2007, aes(x = lifeExp, y = gdpPercap)) + 
  geom_point()
```

Notice how we can change the aesthetics of the plot in different ways.

1.  If we want an aesthetic to be mapped from the data, it must be included inside the call to `aes()`.
2.  If we aren't mapping data onto the plot, then we can specify the aesthetic outside of `aes()`.

Consider the following example:

```{r}
## make the points red
ggplot(df_2007, aes(x = lifeExp, y = gdpPercap)) + 
  geom_point(color = "red")
```

```{r}
## make the points color depend on plant type
ggplot(df_2007, aes(x = lifeExp, y = gdpPercap)) + 
  geom_point(aes(color = continent))
```

### 🔍 Explore! Specifying Color

Does it matter whether you specify the color in the call to `ggplot()` or `geom_point()` in the previous plot? Feel free to experiment.

**Answer here:**

There are lots of geometries to choose from, depending on what type of relationship you are plotting. Some common ones are `geom_histogram()`, `geom_density()`, `geom_boxplot()`, `geom_point()`, and `geom_line()`. You can even build your own geometries!

Let's build a density plot and a histogram that examines the distribution of life expectancy in 2007. The only difference between these plots is the geometry that we use.

```{r}
## density plot
ggplot(df_2007, aes(x = lifeExp)) + 
  geom_density()
```

```{r}
## histogram
ggplot(df_2007, aes(x = lifeExp)) + 
  geom_histogram()
```

We can use the color aesthetic here in a couple of ways. Note that we are actually changing the `fill =` argument, and not the `color =` argument. We will also adjust the opacity of the fill using the `alpha =` argument.

```{r}
## set the fill color to be red
ggplot(df_2007, aes(x = lifeExp)) + 
  geom_density(fill = 'red', alpha = 0.5)
```

```{r}
## make the fill color depend on plant type
ggplot(df_2007, aes(x = lifeExp, fill = continent)) + 
  geom_density(alpha = 0.25)
```

### 🔍 Explore! Color vs. Fill

What is the difference between the `color` and `fill` aesthetics? Experiment with the previous plot.

**Answer here:**

## Facet Plots

------------------------------------------------------------------------

Its common to want to display a set of relationships in facets. This is straightforward using ggplot2.

We use the `facet_grid()` function to build a facet plot.

-   The argument to `facet_grid()` is a formula, which is a special type of R object.
-   For our purposes, we just need to know that we must specify the number of rows and columns that we want.
-   Before the `~` we specify the variable that populates the rows, and after the `~` the columns that populate the columns.
-   If we only want rows or columns populated, use a period to fill the empty condition.

```{r}
## facet by rows
ggplot(df_2007, aes(x = lifeExp)) + 
  geom_density(alpha = 0.5) +
  facet_grid(continent ~ .)
```

```{r}
## facet by columns
ggplot(df_2007, aes(x = lifeExp)) + 
  geom_density(alpha = 0.5) +
  facet_grid(. ~ continent)
```

When you have many levels of one variable that you want to separate into many facets, you can use the `facet_wrap()` function.

-   Here we can specify the number of rows and columns we want.
-   Also notice how we include the variable to be faceted on inside of a call to `vars()`

```{r}
## using facet_wrap()
ggplot(df_2007, aes(x = gdpPercap, y = lifeExp)) + 
  geom_point() +
  facet_wrap(vars(continent), nrow = 2, ncol = 2)
```

One thing to consider when building facet plots is whether or not you want to axes to all be shared. Usually you do want the axes to all have the same scale, but there are certain cases where you don't want axes to be shared.

-   When looking at trends within each facet, and when the range of the data within each facet is very different, you may want to let the axes be free.
-   When looking at trends across all the facets, and in most cases more generally, you want the axes to be shared.

```{r}
## facet by rows and columns
ggplot(df_2007, aes(x = gdpPercap, y = lifeExp)) + 
  geom_point() +
  facet_wrap(vars(continent), nrow = 2, ncol = 2, scales = "free_y")
```

### ✍️ Your Turn! Free Axis or Not?

In the previous example, is it more appropriate to have a shared y-axis, or the to let the y-axis vary across the facets?

**Answer here:**

## Plot Customization

------------------------------------------------------------------------

We can edit plot properties such of axis labels and titles by adding calls to the appropriate functions after more `+` operators. In this way we chain together multiple commands, incrementally adding complexity to our plots.

```{r}
## make nicer labels and add a title
ggplot(df_2007, aes(x = gdpPercap, y = lifeExp)) + 
  geom_point() +
  xlab("GDP Per Capita") +
  ylab("Life Expectancy (Years)") +
  ggtitle("Association in 2007")
```

We can use the `theme()` function to get fine control over thematic components of the plot. We utilize `element_` functions inside of the call to theme to change different types of plotting elements. If we want to remove an element, we use `element_blank()`.

In the next example, we will also show how you can save a plot as a variable, and then make further alterations to a saved plot.

```{r}
## make nicer labels and add a title
my_plot <- ggplot(df_2007, aes(x = gdpPercap, y = lifeExp)) + 
  geom_point() +
  xlab("GDP Per Capita") +
  ylab("Life Expectancy (Years)") +
  ggtitle("Association in 2007")

## print the original plot
my_plot
```

```{r}
## make some further alterations and print
my_plot +
  theme(plot.title = element_text(hjust = 0.5, 
                                  color = "blue", 
                                  size = 20,
                                  family = 'serif'),
        axis.title.x = element_text(size = 10, color = "salmon"),
        panel.grid.minor = element_blank(),
        panel.grid.major = element_line(color = "red"))
```

The ggplot2 package has many built-in collections of these thematic elements, called themes.

```{r}
my_plot + theme_bw()
my_plot + theme_minimal()
```

You can also get additional themes from other R packages. The `ggthemes` package has many interesting themes. Try a few below:

```{r}
my_plot2 <- ggplot(df_2007, 
                   aes(x = lifeExp, fill = continent, color = continent)) + 
  geom_density(alpha = 0.25) +
  ggtitle("Distribution of lifeExp by plant type")

my_plot2 + theme_economist()
my_plot2 + theme_stata()
my_plot2 + theme_fivethirtyeight()
my_plot2 + theme_excel()
```

You can even build you own themes!

## Adding Statistical Summaries

------------------------------------------------------------------------

We can add statistical summaries to our data using `geom_smooth()`. Here we will try a linear and a non-linear fit. We also show how to toggle the standard error on and off.

```{r}
## linear best fitting line
ggplot(df_2007, aes(x = gdpPercap, y = lifeExp)) + 
  geom_point() + 
  geom_smooth(method = 'lm')
```

```{r}
## non-linear best fitting line
ggplot(df_2007, aes(x = gdpPercap, y = lifeExp)) + 
  geom_point() + 
  geom_smooth(method = 'loess', se = FALSE)
```

We can also create summary lines across facets. Next we repeat the graph we just made, but add a facet to examine the difference in the relationship between life expectancy and GDP Per Capita, across the continents.

```{r}
ggplot(df_2007, aes(x = gdpPercap, y = lifeExp)) + 
  geom_point() + 
  geom_smooth(method = 'loess') + 
  facet_grid(continent ~ .)
```

## Saving Plots

------------------------------------------------------------------------

Saving plots is quite straightforward with ggplot2. We simply use the `ggsave()` function! You can save to a variety of file types. We will leave it to you to explore some of the settings you can adjust, such as resolution, aspect ratio, etc.

```{r}
ggsave("Images/my_plot2.jpg", my_plot2)
```

## 📈 EDA: Exploring Continuous Variables

------------------------------------------------------------------------

We examine continuous variables by visually looking at their distribution and by calculating summary statistics. We will begin by examining the distribution of life expectancy for the year 2007.

### Histograms

The main plot for getting a visual representation of a continuous variable is the histogram.

```{r}
## histogram
ggplot(df_2007, aes(x = lifeExp)) + geom_histogram(bins = 30)
```

### ✍️ Your Turn! Describe a Distribution

How would you describe this distribution? Is it normally distributed? Are there any outliers?

**Answer here:**

### Summary Statistics

We can also describe continuous data by collapsing it into single summary statistics. Continuous data is typically described by some measure of *center*, and some measure of *spread*.

### ✍️ Your Turn! Measures of Center and Spread

What are the common measures of center and spread?

**Answer here:**

...

...

...

...

...

...

In the next example we will examine some typical measurements of the central tendency of our data.

```{r}
## summary statistcs
mean(df_2007$lifeExp)
median(df_2007$lifeExp)
```

```{r}
## histogram
ggplot(df_2007, aes(x = lifeExp)) +
  geom_histogram(alpha = 0.5) +
  geom_vline(xintercept = mean(df_2007$lifeExp), 
             color = "red", linetype="dotted") +
  geom_vline(xintercept = median(df_2007$lifeExp), color = "blue") +
  ggtitle("Life Expectancy in 2007")
```

### ✍️ Your Turn! Mean == Median???

When is the mean equal to the median? Is the mean or the median a better statistic to describe the center of this life expectancy data?

**Answer here:**

Spread is often assessed using the standard deviation of the data, or the variance of the data.

```{r}
## measures of spread
var(df_2007$lifeExp)
sd(df_2007$lifeExp)
```

We can use the `summary()` function to get many useful statistics all at once.

```{r}
summary(df_2007$lifeExp)
```

The `describe()` function from the Hmisc package gives even more information.

```{r}
Hmisc::describe(df_2007$lifeExp)
```

One other thing you may want to examine are some specific quantiles of the data.

```{r}
quantile(df_2007$lifeExp, c(0, 0.33, 0.67, 1))
```

### ✍️ Your Turn! Describe The Output

What type of data structure is that previous output?

**Answer here:**

### 🛠️Coding Practice: Subsets Analysis

If you wanted to examine a subset of the data in detail, then you would subset first, followed by calculating summary statistics. Here we will examine the life expectancy in 2017 in countries that had life expectancy of 70 or above. Fill in the blanks in the code below to finish this analysis.

```{r}
## get subset first
# df_2007_gr70 <- df_2007 %>% ________________________

## histogram of life expectancy in high life expectancy countries
# __________________________________

## quantiles amongst this same data set
# __________________________________
```

**END OF EXERCISE**

------------------------------------------------------------------------

## Conclusion

------------------------------------------------------------------------

We hope this was useful! We introduced the grammar of graphics and the ggplot2 package. This is just scratching the surface of what you can do with ggplot2, but should get you setup for success.

## Answers to Questions

------------------------------------------------------------------------

### 🔍 Explore! Specifying Color

Does it matter whether you specify the color in the call to `ggplot()` or `geom_point()` in the previous plot? Feel free to experiment. **Nope! It doesn't really matter if you only have one layer, like points. If you had points and lines on the same plot, but wanted each element to be a different color, then you would specify color in a function like `geom_point()`**.

### 🔍 Explore! Color vs. Fill

What is the difference between the `color` and `fill` aesthetics? Experiment with the previous plot. **It depends on the geom, but for something like a density plot, then `color`** **describes the outline of the shape, while `fill`** **describes the inner section of the shape.**

### ✍️ Your Turn! Free Axis or Not?

In the previous example, is it more appropriate to have a shared y-axis, or the to let the y-axis vary across the facets? **The previous example had different continents in each plot. Here, we probably care about comparing relationships across the continents, so having a shared axis is probably appropriate.**

### ✍️ Your Turn! Describe a Distribution

How would you describe this distribution? Is it normally distributed? Are there any outliers? **There is a strong left skew to this data. It is NOT symmetric. There aren't any obvious outliers from looking at the histogram.**

### ✍️ Your Turn! Measures of Center and Spread

What are the common measures of center and spread?

-   **CENTER: mean, median, mode (mode is the most common category of a discrete variable)**

-   **SPREAD: standard deviation, variance**

### ✍️ Your Turn! Describe The Output

What type of data structure is that previous output? **This is a named vector. The quantiles/percentiles (0%, 33%) are the names and the values (39.6, 62.6) are the elements in the vector.**

### 🛠️Coding Practice: Subsets Analysis

```{r}
## get subset first 
df_2007_gr70 <- df_2007 %>% filter(lifeExp > 70)

## histogram of life expectancy in high life expectancy countries
ggplot(df_2007_gr70, aes(x=lifeExp)) + geom_histogram()
```

```{r}
## quantiles amongst this same data set 
quantile(df_2007_gr70$lifeExp)
```
