Finished draft of visualization chapter. Includes short section on communication.

This commit is contained in:
Garrett 2015-12-13 17:01:56 -05:00
parent 0d3a912e6d
commit 8c82b01d04
1 changed files with 170 additions and 79 deletions

View File

@ -39,9 +39,7 @@ This chapter will teach you how to visualize your data with R and the `ggplot2`
*Section 1* will get you started making graphs right away. You'll learn how to use the grammar of graphics to make any type of plot.
*Section 2* will show you how to use data visualization to explore and understand your data.
*Section 3* will show you how to customize your plots with labels, legends, color schemes, and more.
*Section 2* will show you how to prepare your plots for communication. You'll learn how to make your plots more legible with titles, labels, zooming, and default visual themes.
## Prerequisites
@ -58,9 +56,9 @@ library(ggplot2)
## The Layered Grammar of Graphics
The grammar of graphics is a language for describing graphs. Once you learn the language, you can use it to build graphs with `ggplot2`, but how should you learn the language?
The grammar of graphics is a language for describing graphs. Once you learn the language, you can use it to build graphs with `ggplot2`; but how should you learn the language?
Have you ever tried to learn a language by only studying its rules, vocabulary, and syntax? That's how I tried to learn spanish in college, and now I speak _un muy, muy, poquito_.
Have you ever tried to learn a language by only studying its rules, vocabulary, and syntax? That's how I tried to learn Spanish in college, and now I speak _un muy, muy, poquito_.
It is far better to learn a language by actually speaking it! And that's what we'll do here; we'll learn the grammar of graphics by making a series of plots. Don't worry if things seem confusing at first, by the end of the section everything will come together in a clear way.
@ -85,18 +83,18 @@ library(ggplot2)
### Scatterplots
The easiest way to understand the `mpg` data set is to visualize it, which means that it is time to make our first graph. To do this, open an R session and run the code below. The code plots the `displ` variable of `mpg` against the `hwy` variable to make the graph below. Does the graph confirm your hypothesis about fuel efficiency and engine size?
The easiest way to understand the `mpg` data set is to visualize it, which means that it is time to make our first plot. To do this, open an R session and run the code below. The code plots the `displ` variable of `mpg` against the `hwy` variable to make the plot below. Does the plot confirm your hypothesis about fuel efficiency and engine size?
```{r}
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy))
```
The graph shows a negative relationship between engine size (`displ`) and fuel efficiency (`hwy`). In other words, cars with big engines use more fuel. But the graph shows us something else as well.
The plot shows a negative relationship between engine size (`displ`) and fuel efficiency (`hwy`). In other words, cars with big engines use more fuel. But the plot shows us something else as well.
One group of points seems to fall outside of the linear trend. These cars have a higher mileage than you might expect. Can you tell why? Before we examine these cars, let's review the code that made our graph.
One group of points seems to fall outside of the linear trend. These cars have a higher mileage than you might expect. Can you tell why? Before we examine these cars, let's review the code that made our plot.
`r bookdown::embed_png("images/visualization-1.png", dpi = 300)`
`r bookdown::embed_png("images/visualization-1.png", dpi = 200)`
#### Template
@ -246,7 +244,7 @@ Now that you know how to use aesthetics, take a moment to experiment with the `m
#### Geoms
How are these two plots similar?
You can further enhance your scatterplots by adding summary information to them. But before you can do that with `ggplot2`, you'll need to solve this riddle: how are these two plots similar?
```{r echo = FALSE, message = FALSE, fig.show='hold', fig.width=3, fig.height=3}
ggplot(data = mpg) +
@ -256,13 +254,13 @@ ggplot(data = mpg) +
geom_smooth(mapping = aes(x = displ, y = hwy))
```
They both contain the same x variable, the same y variable, and if you look closely, you can see that they both describe the same data. But the plots are not identical.
Both plots contain the same x variable, the same y variable, and if you look closely, you can see that they both describe the same data. But the plots are not identical.
Each plot uses a different visual object to represent the data. You could say that these two graphs are different "types" of plots, or that they "draw" different things. In `ggplot2` syntax, we say that they use different _geoms_.
A _geom_ is the geometrical object that a plot uses to represent data. People often describe plots by the type of geom that the plot uses. For example, bar charts use bar geoms, line charts use line geoms, boxplots use boxplot geoms, and so on.
A _geom_ is the geometrical object that a plot uses to represent data. People often describe plots by the type of geom that the plot uses. For example, bar charts use bar geoms, line charts use line geoms, boxplots use boxplot geoms, and so on. Scatterplots use the point geom.
As we see above, you can use different geoms to plot the same data. The plot on the left uses the point geom, which is how you create a scatterplot; and the plot on the right uses the smooth geom, a smooth line fitted to the data.
As we see above, you can use different geoms to plot the same data. The plot on the left uses the point geom, and the plot on the right uses the smooth geom, a smooth line fitted to the data.
To change the geom in your plot, change the geom function that you add to `ggplot()`. For instance, you can make the plot on the left with `geom_point()`:
@ -278,35 +276,46 @@ ggplot(data = mpg) +
geom_smooth(mapping = aes(x = displ, y = hwy))
```
Every geom function takes a `mapping` argument. However, the aesthetics that you pass the argument will change from geom to geom. If you think about it, this makes sense. You could set the shape of a point, but you couldn't set the "shape" of a line. On the other hand, you _could_ change the linetype of a line:
Every geom function in `ggplot2` takes a `mapping` argument. However, you'll want to think about which aesthetics you use with which geom. You could set the shape of a point, but you couldn't set the "shape" of a line. On the other hand, you _could_ set the linetype of a line. When you do that `geom_smooth()` will draw a different line, with a different linetype, for each group of points defined by whichever variable you map to linetype.
```{r message = FALSE}
ggplot(data = mpg) +
geom_smooth(mapping = aes(x = displ, y = hwy, linetype = drv))
```
Now `geom_smooth()` separates the cars into three lines based on their `drv` value, which describes a car's drive train. `geom_smooth()` then gives each line a unique linetype. Here, `4` stands for four wheel drive, `f` for front wheel drive, and `r` for rear wheel drive.
Here `geom_smooth()` separates the cars into three lines based on their `drv` value, which describes a car's drive train. One line describes all of the points with a `4` value, one line describes all of the points with an `f` value, and one line describes all of the points with an `r` value. Here, `4` stands for four wheel drive, `f` for front wheel drive, and `r` for rear wheel drive.
```{r message = FALSE}
ggplot(data = mpg) +
geom_smooth(mapping = aes(x = displ, y = hwy, linetype = drv))
If this sounds strange to you, we can make it more clear by overlaying the lines on top of the raw data and then coloring everything according to `drv`.
```{r message = FALSE, echo = FALSE}
ggplot(data = mpg, mapping = aes(x = displ, y = hwy, color = drv)) +
geom_point() +
geom_smooth(mapping = aes( linetype = drv))
```
***
What?! Two geoms in the same graph! If this makes you excited, buckle up. It's time to learn how to place multiple geoms in the same plot.
**Tip** - Many geoms use a single object to describe all of the data. For these geoms, you can ask `ggplot2` to draw a separate object for each group of observations by setting the `group` aesthetic to a discrete variable.
`ggplot2` provides 37 geom functions that you can use to visualize your data. Each geom is particularly well suited for visualizing a certain type of data or a certain type of relationship. The table below lists the geoms in `ggplot2`, loosely organized by the type of relationship that they describe.
In practice, `ggplot2` will automatically detect when it needs to group the data to apply several levels of an aesthetic to a single, monolithic geom (as in the `geom_smooth()` 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 resulting objects.
Next to each geom is a visual representation of the geom. Beneath the geom is a list of aesthetics that apply to the geom. Required aesthetics are listed in bold. Many geoms have very useful arguments that help them do their job. For these geoms, we've listed those arguments in the example code.
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()`.
***
`ggplot2` provides 37 geom functions that you can use to visualize your data. Each geom is particularly well suited for visualizing a certain type of data or a certain type of relationship. The table below lists the geoms in `ggplot2`, loosely organized by the type of relationship that they describe. Next to each geom is a visual representation of the geom. Beneath the geom is a list of aesthetics that apply to the geom.
**Tip** - Many geoms use a single object to describe all of the data, e.g. `geom_smooth()`. For these geoms, you can ask `ggplot2` to draw a separate object for each group of observations by setting the `group` aesthetic to a discrete 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 bookdown::embed_png("images/blank.png", dpi = 300)`
`r bookdown::embed_png("images/visualization-geoms-1.png", dpi = 300)`
***
`r bookdown::embed_png("images/visualization-geoms-2.png", dpi = 300)`
`r bookdown::embed_png("images/visualization-geoms-3.png", dpi = 300)`
`r bookdown::embed_png("images/visualization-geoms-4.png", dpi = 300)`
#### Layers
@ -320,7 +329,7 @@ ggplot(data = mpg) +
Why does this work? You can think of each geom function in `ggplot2` as a layer. When you add multiple geoms to your plot call, `ggplot2` will add multiple layers to your plot. This let's you build sophisticated, multi-layer plots; `ggplot2` will place each new geom on top of the preceeding geoms.
Pay attention to our coding habits whenever you use multiple geoms. Our call now contains some redundant code. We call `mapping = aes(x = displ, y = hwy)` twice. As a general rule, it is unwise to repeat code because each repetition creates a chance to make a typo or error. Repetitions also make your code harder to read and write.
Pay attention to your coding habits whenever you use multiple geoms. Our call now contains some redundant code. We call `mapping = aes(x = displ, y = hwy)` twice. As a general rule, it is unwise to repeat code because each repetition creates a chance to make a typo or error. Repetitions also make your code harder to read and write.
You can avoid repetition by passing a set of mappings to `ggplot()`. `ggplot2` will treat these mappings as global mappings that apply to each geom in the graph. You can then remove the mapping arguments in the individual layers.
@ -439,6 +448,12 @@ ggplot(data = diamonds) +
ggtitle('Position = "identity"')
```
***
**Tip** - You can add a title to your plot by adding `+ ggtitle("<Your Title>")` to your plot call.
***
##### Position = "stack"
`position = "stack"` places overlapping objects directly _above_ one another. This is the default position adjustment for bar charts in `ggplot2`. Here each bar begins exactly where the bar below it ends.
@ -471,7 +486,7 @@ ggplot(data = diamonds) +
##### Position = "jitter"
The last type of position doesn't make sense for bar charts, but it is very useful for scatterplots. Recall our first scatterplot.
The last type of position adjustment does not make sense for bar charts, but it can be very useful for scatterplots. Recall our first scatterplot.
```{r echo = FALSE}
ggplot(data = mpg) +
@ -508,7 +523,7 @@ But isn't random noise, you know, bad? It *is* true that jittering your data wil
#### Stats
Bar charts are interesting because they reveal something subtle about plots. Consider our basic bar chart.
Let's turn our attention back to bar charts for a moment. Bar charts are interesting because they reveal something subtle about plots. Consider our basic bar chart.
```{r echo = FALSE}
ggplot(data = diamonds) +
@ -532,44 +547,17 @@ Some graphs, like scatterplots, plot the raw values of your data set. Other grap
`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.
`r bookdown::embed_png("images/blank.png", dpi = 300)`
`r bookdown::embed_png("images/visualization-stat-bar.png", dpi = 400)`
A few geoms, like `geom_point()`, plot your raw data as it is. To keep things simple, let's imagine that these geoms also transform the data. They just use a very lame transformation, the identity transformation, which returns the data in its original state. Now we can say that _every_ geom uses a stat.
`r bookdown::embed_png("images/blank.png", dpi = 300)`
`r bookdown::embed_png("images/visualization-stat-point.png", dpi = 400)`
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.
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 them? 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. So why bother thinking about stats? Because you can use stats to do three very useful things.
First, you can tell `ggplot2` to use variables created by the stat. For example, the count stat creates two variables, `count` and `prop`, but `geom_bar()` only uses the `count` variable by default.
You can tell `geom_bar()` to use the prop variable by mapping $y$ to `..prop..`. The two dots that surround prop notify `ggplot2` that the prop variable appears in the transformed data set, not the raw data set. Be sure to include these dots whenever you refer to a variable that is created by a stat.
```{r message = FALSE, fig.show='hold', fig.width=4, fig.height=4}
ggplot(data = diamonds) +
geom_bar(mapping = aes(x = cut))
ggplot(data = diamonds) +
geom_bar(mapping = aes(x = cut, y = ..prop.., group = cut))
```
***
**Tip** - The best way to discover which variables are created by a stat is to visit 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`.
***
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 the geom that uses the stat. `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 and how it uses them at the stat's help page.
Finally, you can change the stat that your geom uses by etting 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. Map the $y$ aesthetic to the variable that contains the bar heights.
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. Map the $y$ aesthetic to the variable that contains the bar heights.
```{r}
demo <- data.frame(
@ -585,17 +573,46 @@ ggplot(data = demo) +
Use consideration when you change a geom's stat. Many combinations of geoms and stats will create incompatible results. In practice, I almost always use a geom's default stat.
`ggplot2` provides 22 stats for you to use. The table below describes each stat and lists the command that will open the stat's help page. As of `ggplot2` version 1.0.1.9003, stats share the same help page as the geom that they are most frequently associated with.
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.
```{r}
ggplot(data = diamonds) +
geom_bar(mapping = aes(x = cut), width = 1)
```
***
`r bookdown::embed_png("images/blank.png", dpi = 300)`
**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, the count stat creates two variables, `count` and `prop`, but `geom_bar()` only uses the `count` variable by default. It doesn't make sense to use the `prop` variable for `geom_bar()`, but consider `geom_count()`. `geom_count()` uses the "sum" stat to create bubble charts. Each bubble represents a group, 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 is similar to the count stat because it creates two variables, `n` (count) and `prop`. With `geom_count()`, you can use the prop variable to display the proportion of observations in each row (or column) that appear in the groups. 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 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))
```
`geom_count()` also requires you to set the group aesthetic to either the $x$ or $y$ variable when you use `..prop..`. 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. It saves the stats as functions that begin with the suffix `stat_`. Although you call a stat as a character string surrounded by quotes, e.g. `stat = "identity"`, you would use the full function name to look up the 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. These are the variables that you can call with the `..` syntax, e.g. `..prop..`.
`r bookdown::embed_png("images/visualization-stats.png", dpi = 300)`
### Polar charts
Now that you can make scatterplots and bar charts, let's leave the cartesian coordinate system and examine the polar coordinate system. We will begin with a riddle: how is a bar chart similar to a coxcomb plot, like the one below?
Let's leave the cartesian coordinate system and examine the polar coordinate system for a moment. We will begin with a riddle: how is a bar chart similar to a coxcomb plot, like the one below?
```{r echo = FALSE, message = FALSE, fig.show='hold', fig.width=3, fig.height=4}
ggplot(data = diamonds) +
@ -605,7 +622,7 @@ ggplot(data = diamonds) +
coord_polar()
```
Answer: A coxcomb plot is a bar chart plotted in polar coordinates.
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`.
#### Coordinate systems
@ -626,7 +643,7 @@ In practice, a pie chart is just a stacked bar chart plotted in polar coordinate
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`
3. Add `coord_polar()`
4 Pass `coord_polar()` the argument `theta = "y"`
4. Pass `coord_polar()` the argument `theta = "y"`
```{r}
ggplot(data = diamonds) +
@ -634,13 +651,10 @@ ggplot(data = diamonds) +
coord_polar(theta = "y")
```
`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 function to your plot's call to change the coordinate system that plot uses.
`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.
***
`r bookdown::embed_png("images/visualization-coordinate-systems.png", dpi = 450)`
`r bookdown::embed_png("images/blank.png", dpi = 300)`
***
***
@ -650,9 +664,9 @@ ggplot(data = diamonds) +
#### Facets
Coxcomb plots are especially useful when you make many coxcomb plots to compare against each other. Each coxcomb will act as a glyph that you can use to compare subsets of your data. The quickest way to draw separate coxcombs for subsets of your data is to facet your plot. When you _facet_ a plot, you split it into subplots that each describe a subset of the data.
Coxcomb plots are especially useful when you make many coxcomb plots to compare side-by-side. Each coxcomb will act as a glyph that you can use to compare subsets of your data. The quickest way to draw separate coxcombs for subsets of your data is to facet your plot. When you _facet_ a plot, you split it into subplots that each describe a subset of the data.
To facet your plot on a single discrete variable, add `facet_wrap()` to your plot call. The first argument of `facet_wrap()` is a formula, always a `~` followed by a variable name. For example, here we create a separate subplot for each level of the `clarity` variable. The first subplot displays the group of points that have the `clarity` value `I1`. The second subplot displays the group of points that have the `clarity` value `SI2`. And so on.
To facet your plot on a single discrete variable, add `facet_wrap()` to your plot call. The first argument of `facet_wrap()` is a formula, always a `~` followed by a variable name (here "formula" is the name of a data structure in R, not a synonym for "equation"). For example, here we create a separate subplot for each level of the `clarity` variable. The first subplot displays the group of points that have the `clarity` value `I1`. The second subplot displays the group of points that have the `clarity` value `SI2`. And so on.
```{r fig.height = 7, fig.width = 7}
ggplot(data = diamonds) +
@ -672,6 +686,8 @@ ggplot(data = diamonds) +
Here the first subplot displays all of the points that have an `I1` code for `clarity` _and_ a `D` code for `color`. Don't be confused by the word color here; `color` is a variable name in the `diamonds` data set. It contains the codes `D`, `E`, `F`, `G`, `H`, `I`, and `J`. `facet_grid(color ~ clarity)` is not invoking the color aesthetic.
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}
@ -680,8 +696,6 @@ ggplot(data = mpg) +
facet_wrap(~ class)
```
If you prefer to not facet on the rows or columns dimension, place a `.` instead of a variable name before or after the `~`.
##### Exercises
1. What graph will this code make?
@ -701,7 +715,7 @@ ggplot(data = mpg) +
### The layered grammar of graphics
In this section, you learned more than how to make scatterplots, bar charts, and coxcomb plots; you learned a foundation that you can use to make _any_ type of plot with `ggplot2`.
You may not have realized it, but you learned much more in the previous sections than how to make scatterplots, bar charts, and coxcomb plots. You learned a foundation that you can use to make _any_ type of plot with `ggplot2`.
To see this, let's add position adjustments, stats, coordinate systems, and faceting to our code template. In `ggplot2`, each of these parameters will work with every plot and every geom.
@ -720,15 +734,92 @@ Our new template takes seven parameters, the bracketed words that appear in the
The seven parameters in the template compose the grammar of graphics, a formal system for building plots. The grammar of graphics is based on the insight that you can uniquely describe _any_ plot as a combination of---you guessed it: a data set, a geom, a set of mappings, a stat, a position adjustment, a coordinate system, and a faceting scheme.
To see how this works, consider how you could build a basic plot from scratch: you could start with a data set, transform it into the information that you want to display, choose a geometric object to represent each observation, map aesthetic properties of the objects to variables in the data to visually display the values of the observation. You'd then select a coordinate system to place the objects into. You'd use the location of the objects (which is itself an aesthetic property) to display the values of the x and y variables. At that point, you would have a complete graph, but you could further adjust the positions of the objects or facet the graph if you like. You could also extend the plot by adding one or more additional layers, where each additional layer contains a data set, a geom, a set of mappings, a stat, and a position adjustment.
To see how this works, consider how you could build a basic plot from scratch: you could start with a data set and then transform it into the information that you want to display (with a stat).
***
`r bookdown::embed_png("images/visualization-grammar-1.png", dpi = 400)`
`r bookdown::embed_png("images/blank.png", dpi = 300)`
Next, you could choose a geometric object to represent each observation in the transformed data. You could then map aesthetic properties of the objects to variables in the data to display the values of the observations in a visual manner.
***
`r bookdown::embed_png("images/visualization-grammar-2.png", dpi = 400)`
Although this method may seem complicated, you could use it 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 thousnds of unique plots.
You'd then select a coordinate system to place the objects into. You'd use the location of the objects (which is itself an aesthetic property) to display the values of the x and y variables. At that point, you would have a complete graph, but you could further adjust the positions of the objects or facet the graph if you like. You could also extend the plot by adding one or more additional layers, where each additional layer contains a data set, a geom, a set of mappings, a stat, and a position adjustment.
In the next section, we will use the template to explore a data set. Along the way, we will build several of the most useful graphs for data scientists.
`r bookdown::embed_png("images/visualization-grammar-3.png", dpi = 400)`
Although this method may seem complicated, you could use it 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. Graphs make an excellent communication tool, especially when they are self explanatory. The final section will provide some tips on how to prepare your graphs to share with others.
## Communication with plots
The previous sections showed you how to make plots that you can use as a tools for _exploration_. When you made these plots, you knew---even before you looked at them---which variables the plot would display and which data sets the variables would come from. You might have even known what to look for in the completed plots, assuming that you made each plot with a goal in mind. As a result, it was not very important to put a title or a useful set of labels on your plots.
The importance of titles and labels changes once you use your plots for _communication_. Your audience will not share your background knowledge. In fact, they may not know anything about your plots except what the plots themselves display. If you want your plots to communicate your findings effectively, you will need to make them as self-explanatory as possible.
Luckily, `ggplot2` provides some features that can help you.
### Labels
You can add a title to any `ggplot2` plot by adding the command `labs()` to your plot call. Set the `title` argument of `labs()` to the character string that you would like to appear as the title of your plot. `ggplot2` will place the title at the top of your plot.
```{r}
ggplot(data = mpg, mapping = aes(x = displ, y = hwy)) +
geom_point(mapping = aes(color = class)) +
geom_smooth() +
labs(title = "Fuel efficiency vs. Engine size")
```
You can also use `labs()` to replace the axis and legend labels in your plot, which might be a good idea if your data uses ambiguous or abbreviated variable names. To replace either of the axis labels, set the `x` or `y` arguments to a character string. `ggplot2` will replace the associated axis label with your character string.
```{r}
ggplot(data = mpg, mapping = aes(x = displ, y = hwy)) +
geom_point(mapping = aes(color = class)) +
geom_smooth() +
labs(title = "Fuel efficiency vs. Engine size",
x = "Engine displacement (L)",
y = "Highway fuel efficiency (mpg)")
```
To replace a legend label, set the name of the aesthetic displayed in the legend to the character string that should appear as the title of the legend. For example, the legend in our plot corresponds to the color aesthetic. We can change it's title with the command, `labs(color = "New Title")`, or, more usefully:
```{r}
ggplot(data = mpg, mapping = aes(x = displ, y = hwy)) +
geom_point(mapping = aes(color = class)) +
geom_smooth() +
labs(title = "Fuel efficiency vs. Engine size",
x = "Engine displacement (L)",
y = "Highway fuel efficiency (mpg)",
color = "Type of Car")
```
### Zooming
Often, it can be helpful to zoom in on a specific region of your plot. In `ggplot2` you can do this by adding `coord_cartesian()` to your plot and setting it's `xlim` and `ylim` arguments. Pass each argument a vector of two numbers, the minimum value to display on that axis and the maximum value, e.g.
```{r}
ggplot(data = mpg, mapping = aes(x = displ, y = hwy)) +
geom_point(mapping = aes(color = class)) +
geom_smooth() +
coord_cartesian(xlim = c(5, 7), ylim = c(10, 30))
```
`coord_cartesian()` adds a cartesian coordinate system to your plot (which is the default coordinate system). However, the new coordinate system will use the zoomed in limits.
What if your plot uses a different coordinate system? Most of the other coordinate functions also take `xlim` and `ylim` arguments. You can look up the help pages of the coordinate functions to learn more.
### Themes
Finally, you can also quickly customize the "look" of your plot by adding a theme function to your plot call. This can be a useful thing to do, for example, if you'd like to save ink when you print your plots, or if you wish to ensure that the plots photocopy well.
`ggplot2` contains eight theme functions, listed in the table below. Each applies a different visual theme to your finished plot. You can think of the themes as "skins" for the plot. The themes change how the plot looks without changing the information that the plot displays.
To use any of the theme functions, add the function to your plot all. No arguments are necessary.
```{r}
ggplot(data = mpg, mapping = aes(x = displ, y = hwy)) +
geom_point(mapping = aes(color = class)) +
geom_smooth() +
theme_bw()
```
`r bookdown::embed_png("images/visualization-themes.png", dpi = 450)`