Edits visualization chapter.

This commit is contained in:
Garrett 2016-05-19 11:31:02 -04:00
parent 5495ee3966
commit d895dbee9d
1 changed files with 68 additions and 106 deletions

View File

@ -2,29 +2,11 @@
> "The simple graph has brought more information to the data analysts mind than any other device."---John Tukey
If you are like most humans, your brain is not designed to work with raw data. The working memory can only attend to a few values at a time, which makes it difficult to discover patterns in raw data. For example, can you spot the striking relationship between $X$ and $Y$ in the table below?
```{r data, echo=FALSE}
x <- rep(seq(0.2, 1.8, length = 5), 2) + runif(10, -0.15, 0.15)
X <- c(0.02, x, 1.94)
Y <- sqrt(1 - (X - 1)^2)
Y[1:6] <- -1 * Y[1:6]
Y <- Y - 1
order <- sample(1:10)
knitr::kable(round(data.frame(X = X[order], Y = Y[order]), 2))
```
While we may stumble over raw data, we can easily process visual information. Within your mind is a visual processing system that has been fine-tuned by thousands of years of evolution. As a result, the quickest way to understand your data is to visualize it. Once you plot your data, you can instantly see the relationships between values. Here, we see that the values above fall on a circle.
```{r echo=FALSE, dependson=data}
ggplot2::qplot(X, Y) + ggplot2::coord_fixed(ylim = c(-2.5, 2.5), xlim = c(-2.5, 2.5))
```
This chapter will teach you how to visualize your data with R and the `ggplot2` package. R contains several systems for making graphs, but the `ggplot2` system is one of the most beautiful and most versatile. `ggplot2` implements the *grammar of graphics*, a coherent system for describing and building graphs. With `ggplot2`, you can do more faster by learning one system and applying it in many places.
### Prerequisites
To access the data sets and functions that we will use in this chapter, load the `ggplot2` package:
To access the data sets, help pages, and functions that we will use in this chapter, load the `ggplot2` package:
```{r echo = FALSE, message = FALSE, warning = FALSE}
library(ggplot2)
@ -37,7 +19,7 @@ library(ggplot2)
## A code template
Let's use our first graph to answer a question: Do cars with big engines use more fuel than cars with small engines? You probably already have an answer, but try to make your answer precise. What does the relationship between engine size and fuel efficieny look like? Is it positive? Negative? Linear? Nonlinear? Strong? Weak?
Let's use our first graph to answer a question: Do cars with big engines use more fuel than cars with small engines? You probably already have an answer, but try to make your answer precise. What does the relationship between engine size and fuel efficieny look like? Is it positive? Negative? Linear? Nonlinear?
You can test your answer with the `mpg` data set in the `ggplot2` package. The data set contains observations collected by the EPA on 38 models of car. Among the variables in `mpg` are
@ -46,16 +28,6 @@ You can test your answer with the `mpg` data set in the `ggplot2` package. The d
To learn more about `mpg`, open its help page with the command `?mpg`.
***
*Tip*: If you have trouble loading `mpg`, its help page, or any of the functions in this chapter, you may need to reload the `ggplot2` package with the command below. You will need to reload the package each time you start a new R session.
```{r eval=FALSE}
library(ggplot2)
```
***
To plot `mpg`, open an R session and run the code below. The code plots the `displ` variable of `mpg` against the `hwy` variable.
```{r}
@ -65,7 +37,7 @@ ggplot(data = mpg) +
The plot shows a negative relationship between engine size (`displ`) and fuel efficiency (`hwy`). In other words, cars with big engines use more fuel. Does this confirm your hypothesis about fuel efficiency and engine size?
Our code is almost a template for making plots with `ggplot2`.
Pay close attention to this code because it is almost a template for making plots with `ggplot2`.
```{r eval=FALSE}
ggplot(data = mpg) +
@ -74,18 +46,18 @@ ggplot(data = mpg) +
With `ggplot2`, you begin a plot with the function `ggplot()`. `ggplot()` creates a coordinate system that you can add layers to. The first argument of `ggplot()` is the data set to use in the graph. So `ggplot(data = mpg)` creates an empty graph that will use the `mpg` data set.
You complete your graph by adding one or more layers to `ggplot()`. Here, the function `geom_point()` adds a layer of points to your plot, which creates a scatterplot. `ggplot2` comes with many geom functions that each add a different type of layer to a plot. Each geom function in `ggplot2` takes a mapping argument.
You complete your graph by adding one or more layers to `ggplot()`. Here, the function `geom_point()` adds a layer of points to your plot, which creates a scatterplot. `ggplot2` comes with many geom functions that each add a different type of layer to a plot.
The mapping argument of your geom function explains where your points should go. You must set `mapping` to a call to `aes()`. The `x` and `y` arguments of `aes()` explain which variables to map to the x and y axes of your plot. `ggplot()` will look for those variables in your data set, `mpg`.
Each geom function in `ggplot2` takes a mapping argument. The mapping argument of your geom function explains where your points should go. You must set `mapping` to a call to `aes()`. The `x` and `y` arguments of `aes()` explain which variables to map to the x and y axes of your plot. `ggplot()` will look for those variables in your data set, `mpg`.
This code suggests a reusable template for making graphs with `ggplot2`. To make a graph, replace the bracketed sections in the code below with a data set, a geom function, or a set of mappings.
Let's turn this code into a reusable template for making graphs with `ggplot2`. To make a graph, replace the bracketed sections in the code below with a data set, a geom function, or a set of mappings.
```{r eval = FALSE}
ggplot(data = <DATA>) +
<GEOM_FUNCTION>(mapping = aes(<MAPPINGS>))
```
The sections below will show you how to complete and extend this template to make a graph. We will begin with `<MAPPINGS>`.
The rest of this chapter will show you how to complete and extend this template to make different types of graphs. We will begin with the `<MAPPINGS>` component.
## Aesthetic mappings
@ -120,7 +92,7 @@ The colors reveal that many of the unusual points are two seater cars. These car
In the above example, we mapped `class` to the color aesthetic, but we could have mapped `class` to the size aesthetic in the same way. In this case, the exact size of each point would reveal its class affiliation.
```{r}
```{r warning=FALSE}
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy, size = class))
```
@ -139,13 +111,9 @@ ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy, shape = class))
```
***
What happened to the suv's? `ggplot2` will only use six shapes at a time. Additional groups will go unplotted when you use this aesthetic.
**Tip** - What happened to the suv's? `ggplot2` will only use six shapes at a time. Additional groups will go unplotted when you use this aesthetic.
***
In each case, you set the name of the aesthetic to the variable to display, and you do this within the `aes()` function. The `aes()` function gathers together each of the aesthetic mappings used by a layer and passes them to the layer's mapping argument. The syntax highlights a useful insight because you also set `x` and `y` to variables within `aes()`. The insight is that the x and y locations of a point are themselves aesthetics, visual properties that you can map to variables to display information about the data.
For each aesthetic, you set the name of the aesthetic to the variable to display, and you do this within the `aes()` function. The `aes()` function gathers together each of the aesthetic mappings used by a layer and passes them to the layer's mapping argument. The syntax highlights a useful insight because you also set `x` and `y` to variables within `aes()`. The insight is that the x and y locations of a point are themselves aesthetics, visual properties that you can map to variables to display information about the data.
Once you set an aesthetic, `ggplot2` takes care of the rest. It selects a pleasing set of levels to use for the aesthetic, and it constructs a legend that explains the mapping between levels and values. For x and y aesthetics, `ggplot2` does not create a legend, but it creates an axis line with tick marks and a label. The axis line acts as a legend; it explains the mapping between locations and values.
@ -156,7 +124,7 @@ ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy), color = "blue")
```
Here, the color doesn't convey information about a variable. It only changes the appearance of the plot. To set an aesthetic manually, do not plce it in the `aes()` function. Call the aesthetic by name as an argument of your geom function. Then pass the aesthetic a value that R will recognize, such as
Here, the color doesn't convey information about a variable. It only changes the appearance of the plot. To set an aesthetic manually, do not place it in the `aes()` function. Call the aesthetic by name as an argument of your geom function. Then pass the aesthetic a level that R will recognize, such as
* the name of a color as a character string
* the size of a point as a cex expansion factor (see `?par`)
@ -193,10 +161,10 @@ pchShow <-
pchShow()
```
If you get an odd result, double check that you are calling the aesthetic as its own argument (and not calling it from inside of `mapping = aes()`. We like to think of aesthetics like this, if you set the aesthetic:
If you get an odd result, double check that you are calling the aesthetic as its own argument (and not calling it from inside of `mapping = aes()`). I like to think of aesthetics like this, if you set the aesthetic:
* _inside_ of the `aes()` function, `ggplot2` will map the aesthetic to data values and build a legend.
* _outside_ of the `aes()` function, `ggplot2` will directly set the aesthetic to your input.
* _inside_ of the `aes()` function, `ggplot2` will **map** the aesthetic to data values and build a legend.
* _outside_ of the `aes()` function, `ggplot2` will **set** the aesthetic to a level that you supply manually.
### Exercises
@ -270,17 +238,35 @@ Next to each geom is a visual representation of the geom. Beneath the geom is a
To learn more about any single geom, open it's help page in R by running the command `?` followed by the name of the geom function, e.g. `?geom_smooth`.
***
```{r, echo = FALSE}
knitr::include_graphics("images/visualization-geoms-1.png")
```
**Tip** - Many geoms use a single object to describe all of the data. For example, `geom_smooth()` uses a single line. For these geoms, you can set the group aesthetic to a discrete variable to draw multiple objects. `ggplot2` will draw a separate object for each unique value of the grouping variable.
```{r, echo = FALSE}
knitr::include_graphics("images/visualization-geoms-2.png")
```
```{r, echo = FALSE}
knitr::include_graphics("images/visualization-geoms-3.png")
```
```{r, echo = FALSE}
knitr::include_graphics("images/visualization-geoms-4.png")
```
Many geoms use a single object to describe all of the data. For example, `geom_smooth()` uses a single line. For these geoms, you can set the group aesthetic to a discrete variable to draw multiple objects. `ggplot2` will draw a separate object for each unique value of the grouping variable.
In practice, `ggplot2` will automatically group the data for these geoms whenever you map an aesthetic to a discrete variable (as in the `linetype` example). It is convenient to rely on this feature because the group aesthetic by itself does not add a legend or distinguishing features to the geoms.
```{r, echo = FALSE}
knitr::include_graphics("images/visualization-geoms-1.png")
knitr::include_graphics("images/visualization-geoms-2.png")
knitr::include_graphics("images/visualization-geoms-3.png")
knitr::include_graphics("images/visualization-geoms-4.png")
```{r, fig.show='hold', fig.height = 2.5, fig.width = 2.5}
ggplot(diamonds) +
geom_smooth(aes(x = carat, y = price))
ggplot(diamonds) +
geom_smooth(aes(x = carat, y = price, group = cut))
ggplot(diamonds) +
geom_smooth(aes(x = carat, y = price, color = cut))
```
## Layers
@ -301,7 +287,7 @@ ggplot(data = mpg, mapping = aes(x = displ, y = hwy)) +
geom_smooth()
```
If you place mappings in a geom function, `ggplot2` will treat them as local mappings. It will use these mappings to extend or overwrite the global mappings _for that geom only_. This provides an easy way to differentiate geoms.
If you place mappings in a geom function, `ggplot2` will treat them as local mappings for the layer. It will use these mappings to extend or overwrite the global mappings _for that layer only_. This provides an easy way to differentiate layers.
```{r, message = FALSE}
ggplot(data = mpg, mapping = aes(x = displ, y = hwy)) +
@ -309,12 +295,12 @@ ggplot(data = mpg, mapping = aes(x = displ, y = hwy)) +
geom_smooth()
```
You can use the same system to specify individual data sets for each layer. Here, our smooth line displays just a subset of the `mpg` data set, the cars with eight cylinder engines. The local data argument in `geom_smooth()` overrides the global data argument in `ggplot()` for the smooth layer only.
You can use the same system to specify individual data sets for each layer. Here, our smooth line displays just a subset of the `mpg` data set, the subcompact cars. The local data argument in `geom_smooth()` overrides the global data argument in `ggplot()` for the smooth layer only.
```{r, message = FALSE, warning = FALSE}
ggplot(data = mpg, mapping = aes(x = displ, y = hwy)) +
geom_point() +
geom_smooth(data = subset(mpg, cyl == 8))
geom_point(aes(color = class)) +
geom_smooth(data = subset(mpg, class == "subcompact"))
```
### Exercises
@ -423,7 +409,7 @@ ggplot(data = diamonds) +
### Position = "fill"
`position = "fill"` places overlapping objects above one another. However, it scales the objects to take up all of the available vertical space. As a result, `position = "fill"` makes it easy to compare relative frequencies across groups.
`position = "fill"` places overlapping objects above one another. However, it scales the objects to take up all of the available vertical space. As a result, `position = "fill"` makes it easy to compare relative proportions across groups.
```{r}
ggplot(data = diamonds) +
@ -460,19 +446,11 @@ ggplot(data = mpg) +
ggtitle('Position = "jitter"')
```
But isn't random noise, you know, bad? It *is* true that jittering your data will make it less accurate at the local level, but jittering may make your data _more_ accurate at the global level. Occasionally, jittering will reveal a pattern that was hidden within the grid.
This may seem like a bad idea since jittering will make your graph less accurate at the local level, but jittering may make your graph _more_ revealing at the global level. Occasionally, jittering will reveal a pattern that was hidden within the grid.
***
`ggplot2` comes with a special geom `geom_jitter()` that is the exact equivalent of `geom_point(position = "jitter")`.
**Tip** - `ggplot2` comes with a special geom `geom_jitter()` that is the exact equivalent of `geom_point(position = "jitter")`.
***
***
**Tip** - To learn more about a position adjustment, look up the help page associated with each adjustment: `?position_dodge`, `?position_fill`, `?position_identity`, `?position_jitter`, and `?position_stack`.
***
To learn more about a position adjustment, look up the help page associated with each adjustment: `?position_dodge`, `?position_fill`, `?position_identity`, `?position_jitter`, and `?position_stack`.
## Stats
@ -491,14 +469,14 @@ head(diamonds)
Where does count come from?
Some graphs, like scatterplots, plot the raw values of your data set. Other graphs, like bar charts, do not plot raw values at all. These graphs apply an algorithm to your data and then plot the results of the algorithm. Consider how often graphs do this.
Some graphs, like scatterplots, plot the raw values of your data set. Other graphs, like bar charts, calculate new values to plot.
* **bar charts** and **histograms** bin your data and then plot bin counts, the number of points that fall in each bin.
* **smooth lines** fit a model to your data and then plot the model line.
* **boxplots** calculate the quartiles of your data and then plot the quartiles as a box.
* and so on.
`ggplot2` calls the algorithm that a graph uses to transform raw data a _stat_, which is short for statistical transformation. Each geom in `ggplot2` is associated with a default stat that it uses to plot your data. `geom_bar()` uses the "count" stat, which computes a data set of counts for each x value from your raw data. `geom_bar()` then uses this computed data to make the plot.
`ggplot2` calls the algorithm that a graph uses to calculate new values a _stat_, which is short for statistical transformation. Each geom in `ggplot2` is associated with a default stat that it uses to calculate values to plot. The figure below describes how this process works with `geom_bar()`.
```{r, echo = FALSE}
knitr::include_graphics("images/visualization-stat-bar.png")
@ -511,11 +489,11 @@ A few geoms, like `geom_point()`, plot your raw data as it is. These geoms also
knitr::include_graphics("images/visualization-stat-point.png")
```
You can learn which stat a geom uses, as well as what variables it computes by visiting the geom's help page. For example, the help page of `geom_bar()` shows that it uses the count stat and that the count stat computes two new variables, `count` and `prop`. If you have an R session open---and you should!---you can verify this by running `?geom_bar` at the command line.
You can learn which stat a geom uses, as well as what variables it computes by visiting the geom's help page. For example, the help page of `geom_bar()` shows that it uses the count stat and that the count stat computes two new variables, `count` and `prop`. If you have an R session open you can verify this by running `?geom_bar` at the command line.
Stats are the most subtle part of plotting because you do not see them in action. `ggplot2` applies the transformation and stores the results behind the scenes. You only see the finished plot. Moreover, `ggplot2` applies stats automatically, with a very intuitive set of defaults. So why bother thinking about stats? Because you can use stats to do three very useful things.
Stats are the most subtle part of plotting because you do not see them in action. `ggplot2` applies the transformation and stores the results behind the scenes. You only see the finished plot. Moreover, `ggplot2` applies stats automatically, with a very intuitive set of defaults. As a result, you rarely need to adjust a geom's stat. However, you can do three things with a geom's stat if you wish to.
First, you can change the stat that a geom uses. To do this, set the geom's stat argument. For example, you can map the heights of your bars to raw values---not counts---if you change the stat of `geom_bar()` from "count" to "identity". This works best if your data contains one value per bar, as in the demo data set below. Add a $y$ aesthetic, and map it to the variable that contains the bar heights.
First, you can change the stat that the geom uses with the geom's stat argument. In the code below, I change the stat of `geom_bar()` from count (the default) to identity. This let's me map the height of the bars to the raw values of a $y$ variable.
```{r}
demo <- data.frame(
@ -523,44 +501,42 @@ demo <- data.frame(
b = c(20, 30, 40)
)
demo
ggplot(data = demo) +
geom_bar(mapping = aes(x = a, y = b), stat = "identity")
demo
```
Use consideration when you change a geom's stat. Many combinations of geoms and stats will create incompatible results. In practice, you will almost always use a geom's default stat.
I provide a list of the stats that are availalbe to use in ggplot2 at the end of this section. Be careful when you change a geom's stat. Many combinations of geoms and stats will create incompatible results. In practice, you will almost always use a geom's default stat.
Second, you can customize how a stat does its job. For example, the count stat takes a width parameter that it uses to set the widths of the bars in a bar plot. To pass a width value to the stat, provide a width argument to your geom function. `width = 1` will make the bars wide enough to touch each other.
Second, you can give some stats arguments by passing the arguments to your geom function. In the code below, I pass a width argument to the count stat, which controls the widths of the bars. `width = 1` will make the bars wide enough to touch each other.
```{r}
ggplot(data = diamonds) +
geom_bar(mapping = aes(x = cut), width = 1)
```
***
You can learn which arguments a stat takes at the stat's help page. To open the help page, place the prefix `?stat_` before the name of the stat, then run the command at the command line, e.g. `?stat_count`.
**Tip** - You can learn which arguments a stat takes and how it uses them at the stat's help page. To open the help page, place the prefix `?stat_` before the name of the stat, then run the command at the command line, e.g. `?stat_count`.
***
Finally, you can tell `ggplot2` how to use the stat. Many stats in `ggplot2` create multiple variables, some of which go unused. For example, `geom_count()` uses the "sum" stat to create bubble charts. Each bubble represents a group of data points, and the size of the bubble displays how many points are in the group (e.g. the count of the group).
Finally, you can use extra variables created by the stat. Many stats in `ggplot2` create multiple variables, some of which go unused. For example, `geom_count()` uses the "sum" stat to create bubble charts. Each bubble represents a group of data points, and the size of the bubble displays how many points are in the group (e.g. the count of the group).
```{r}
ggplot(data = diamonds) +
geom_count(mapping = aes(x = cut, y = clarity))
```
The sum stat creates two variables, `n` (count) and `prop`. By default, `geom_count()` uses the `n` variable to create the size of each bubble. You can use the prop variable in combination with a _group_ aesthetic to display the proportion of observations in each row (or column) that appear in the bubbles. To tell `geom_count()` to use the prop variable, map $size$ to `..prop..`. The two dots that surround prop notify `ggplot2` that the prop variable appears in the transformed data set that is created by the stat, and not in the raw data set. Be sure to include these dots whenever you refer to a variable that is created by a stat.
The help page of `?stat_sum` reveals that the sum stat creates two variables, n (count) and prop. By default, `geom_count()` uses the n variable to create the size of each bubble. To tell `geom_count()` to use the prop variable, map $size$ to `..prop..`. The two dots that surround prop notify `ggplot2` that the prop variable appears in the transformed data set that is created by the stat, and not in the raw data set. Be sure to include these dots whenever you refer to a variable that is created by a stat.
```{r}
ggplot(data = diamonds) +
geom_count(mapping = aes(x = cut, y = clarity, size = ..prop.., group = clarity))
```
If you set _group_ to the $x$ variable, `..prop..` will show proportions across columns. If you set it to the $y$ variable, `..prop..` will show proportions across rows, as in the plot above. Here, the proportions in each row sum to one.
For `geom_count()`, the `..prop..` variable does not do anything useful until you set a group aesthetic. If you set _group_ to the $x$ variable, `..prop..` will show proportions across columns. If you set it to the $y$ variable, `..prop..` will show proportions across rows, as in the plot above. Here, the proportions in each row sum to one.
The best way to discover which variables are created by a stat is to visit the stat's help page. `ggplot2` provides 22 stats for you to use. Each stat is saved as a function, which provides a convenient way to access a stat's help page, e.g. `?stat_identity`.
In most cases, you will not want to switch the default variable supplied by a stat. Many stats only return one useful variable. The best way to discover which variables are created by a stat is to visit the stat's help page.
`ggplot2` provides 22 stats for you to use. Each stat is saved as a function, which provides a convenient way to access a stat's help page, e.g. `?stat_identity`.
The table below describes each stat in `ggplot2` and lists the parameters that the stat takes, as well as the variables that the stat makes.
@ -580,7 +556,7 @@ ggplot(data = diamonds) +
coord_polar()
```
Answer: A coxcomb plot is a bar chart plotted in polar coordinates. If this seems surprising, consider how you would make a coxcomb plot with `ggplot2`.
A coxcomb plot is a bar chart plotted in polar coordinates. If this seems surprising, consider how you would make a coxcomb plot with `ggplot2`.
To make a coxcomb plot, first build a bar chart and then add `coord_polar()` to your plot call. Polar bar charts will look better if you also set the width parameter of `geom_bar()` to 1. This will ensure that no space appears between the bars.
@ -592,7 +568,7 @@ ggplot(data = diamonds) +
You can use `coord_polar()` to turn any plot in `ggplot2` into a polar chart. Whenever you add `coord_polar()` to a plot's call, `ggplot2` will draw the plot on a polar coordinate system. It will map the plot's $y$ variable to $r$ and the plot's $x$ variable to $\theta$. You can reverse this behavior by passing `coord_polar()` the argument `theta = "y"`.
Polar coordinates unlock another riddle as well. You may have noticed that `ggplot2` does not come with a pie chart geom. Why would that be? In practice, a pie chart is just a stacked bar chart plotted in polar coordinates. To make a pie chart in `ggplot2`, create a stacked bar chart and:
Polar coordinates unlock another riddle as well. You may have noticed that `ggplot2` does not come with a pie chart geom. In practice, a pie chart is a stacked bar chart plotted in polar coordinates. To make a pie chart in `ggplot2`, create a stacked bar chart and:
1. ensure that the x axis only has one value. An easy way to do this is to set `x = factor(1)`.
2. set the width of the bar to one, e.g. `width = 1`
@ -607,17 +583,12 @@ ggplot(data = diamonds) +
`ggplot2` comes with eight coordinate functions that you can use in the same way as `coord_polar()`. The table below describes each function and what it does. Add any of these functions to your plot's call to change the coordinate system that the plot uses.
***
You can learn more about each coordinate system by opening its help page in R, e.g. `?coord_cartesian`, `?coord_fixed`, `?coord_flip`, `?coord_map`, `?coord_polar`, and `?coord_trans`.
```{r, echo = FALSE}
knitr::include_graphics("images/visualization-coordinate-systems.png")
```
***
**Tip** - You can learn more about each coordinate system by opening its help page in R, e.g. `?coord_cartesian`, `?coord_fixed`, `?coord_flip`, `?coord_map`, `?coord_polar`, and `?coord_trans`.
***
## Facets
@ -632,7 +603,7 @@ ggplot(data = diamonds) +
facet_wrap( ~ clarity)
```
To facet your plot on the combinations of two variables, add `facet_grid()` to your plot call. The first argument of `facet_grid()` is also a formula. This time the formula should contain two variable names separated by a `~`.
To facet your plot on the combination of two variables, add `facet_grid()` to your plot call. The first argument of `facet_grid()` is also a formula. This time the formula should contain two variable names separated by a `~`.
```{r fig.height = 7, fig.width = 7}
ggplot(data = diamonds) +
@ -645,13 +616,7 @@ Here the first subplot displays all of the points that have an `I1` code for `cl
If you prefer to not facet on the rows or columns dimension, place a `.` instead of a variable name before or after the `~`, e.g. `+ facet_grid(. ~ clarity)`.
Faceting works on more than just polar charts. You can add `facet_wrap()` or `facet_grid()` to any plot in `ggplot2`. For example, you could facet our original scatterplot.
```{r fig.height = 6, fig.width = 6}
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy)) +
facet_wrap(~ class)
```
Faceting works on more than just polar charts. You can add `facet_wrap()` or `facet_grid()` to any plot in `ggplot2`.
### Exercises
@ -699,7 +664,6 @@ To see how this works, consider how you could build a basic plot from scratch: y
knitr::include_graphics("images/visualization-grammar-1.png")
```
***
Next, you could choose a geometric object to represent each observation in the transformed data. You could then use the aesthetic properties of the geoms to represent variables in the data. You would map the values of each variable to the levels of an aesthetic.
```{r, echo = FALSE}
@ -713,5 +677,3 @@ knitr::include_graphics("images/visualization-grammar-3.png")
```
You could use this method to build _any_ plot that you imagine. In other words, you can use the code template that you've learned in this chapter to build hundreds of thousands of unique plots.
You could use these plots to explore and understand your data. Or you could use them to share insights about your data with others. Chapter ? will provide some tips on how to use graphs to discover insights in your data. Chapter ? will provide some tips on how to prepare your graphs to share with others. Graphs make an excellent communication tool, especially when they are self explanatory.