More work on visualization. Adds histogram diagrams.

This commit is contained in:
Garrett 2015-11-30 10:33:44 -05:00
parent 619e212a81
commit 07324d555c
5 changed files with 473 additions and 109 deletions

BIN
images/visualization-17.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

BIN
images/visualization-18.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

BIN
images/visualization-19.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

BIN
images/visualization-20.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

View File

@ -36,7 +36,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 make several common types of plots, and how to use the `ggplot2` syntax.
*Section 2* will guide you through the geoms, stats, position adjustments, coordinate systems, and facetting schemes that you can use to make many different types of plots with `ggplot2`.
*Section 2* will guide you through the geoms, stats, position adjustments, coordinate systems, and facetting schemes that you can use to make different types of plots with `ggplot2`.
*Section 3* will teach you the _layered grammar of graphics_, a versatile system for building multi-layered plots that underlies `ggplot2`.
@ -57,38 +57,37 @@ library(ggplot2)
## Basics
Before we look at any graphs, let's begin with a question to explore: Do cars with big engines use more fuel than cars with small engines?
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 have an intuitive 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?
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?
You can test your hypothesis 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 `displ`, a car's engine size in litres, and `hwy`, a car's fuel efficiency on the highway in miles per gallon (mpg). A car with a low fuel efficiency consumes more fuel than a car with a high fuel efficiency when they travel the same distance.
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
1. `displ` - a car's engine size in litres, and
2. `hwy` - a car's fuel efficiency on the highway in miles per gallon (mpg). A car with a low fuel efficiency consumes more fuel than a car with a high fuel efficiency when they travel the same distance.
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 load the `ggplot2` package with the command
*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)
```
You will need to reload the package each time you start a new R session.
***
### 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.
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.
```{r}
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy))
```
Your result will look like the graph above. Does the graph confirm your hypothesis about fuel and engine size?
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.
Does the graph confirm your hypothesis about fuel efficiency and engine size? 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.
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.
@ -107,9 +106,9 @@ With `ggplot2`, you begin a plot with the function `ggplot()`. `ggplot()` doesn'
The first argument of `ggplot()` is the data set to use in the graph. So `ggplot(data = mpg)` initializes a 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 the plot, which creates a scatterplot. `ggplot2` comes with other `geom_` functions that you can use as well. Each function creates a different type of layer, and each function takes a mapping argument. We'll learn about all of the geom functions in Section 2.
You complete your graph by adding one or more layers to `ggplot()`. Here, the function `geom_point()` adds a layer of points to the plot, which creates a scatterplot. `ggplot2` comes with other `geom_` functions that you can use as well. Each function creates a different type of layer, and each function takes a mapping argument. You'll learn about all of the geom functions in Section 2.
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 the graph. `ggplot()` will look for those variables in your data set, `mpg`.
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 the graph. `ggplot()` will look for those variables in your data set, `mpg`.
This code suggests a template for making graphs with `ggplot2`. To make a graph, replace the bracketed sections in the code below with a new data set, a new geom function, or a new set of mappings.
@ -118,7 +117,7 @@ ggplot(data = <DATA>) +
<GEOM_FUNCTION>(mapping = aes(<MAPPINGS>))
```
The next few subsections will introduce several arguments (and functions) that you can add to the template. Each argument will come with a new set of options---and likely a new set of questions. Hold those questions for now. We will catalogue your options in Section 2. Use this section to become familiar with the `ggplot2` syntax. Once you do, the low level details of `ggplot2` will be easier to understand.
The remainder of this section will introduce several arguments (and functions) that you can add to the template. Each argument will come with a new set of options---and likely a new set of questions. Hold those questions for now. We will catalogue your options in Section 2. Use this section to become familiar with the `ggplot2` syntax. Once you do, the low level details of `ggplot2` will be easier to understand.
#### Aesthetic Mappings
@ -130,7 +129,7 @@ Let's hypothesize that the cars are hybrids. One way to test this hypothesis is
You can add a third value, like `class`, to a two dimensional scatterplot by mapping it to an _aesthetic_.
An aesthetic is a visual property of the points in your plot. Aesthetics include things like the size, the shape, or the color of your points. You can display a point (like the one below) in different ways by changing its aesthetic properties.
An aesthetic is a visual property of the points in your plot. Aesthetics include things like the size, the shape, or the color of your points. You can display a point (like the one below) in different ways by changing the values of its aesthetic properties. Since we already use the word "value" to describe data, let's use the word "level" to describe aesthetic properties. Here we change the levels of a point's size, shape, and color properties to make the point small, trianglular, or blue.
`r bookdown::embed_png("images/visualization-2.png", dpi = 150)`
@ -201,7 +200,9 @@ ggplot(data = mpg) +
The points appear in a grid because the `hwy` and `displ` measurements in `mpg` are rounded to the nearest integer and tenths values. This also explains why our graph appears to contain 126 points. Many points overlap each other because they have been rounded to the same values of `hwy` and `displ`. 108 points are hidden on top of other points located at the same value.
You can avoid this overplotting problem by setting the position argument of `geom_point()` to "jitter". `position = "jitter"` adds a small amount of random noise to each point. This spreads the points out since no two points are likely to receive the same amount of random noise.
You can avoid this overplotting problem by adjusting the position of the points. Each geom function uses a position argument to determine how to adjust the position of objects that overlap.
The most useful type of adjustment for scatterplots is known as a "jitter". Jittering adds a small amount of random noise to each point. This spreads the points out since no two points are likely to receive the same amount of random noise. To jitter your points, add `position = "jitter"` to `geom_point`.
```{r}
ggplot(data = mpg) +
@ -254,15 +255,13 @@ ggplot(data = diamonds) +
geom_bar(mapping = aes(x = cut, fill = clarity))
```
Bar charts also use different position adjustments than scatterplots. Every geom function in `ggplot2` accepts a position argument, but it wouldn't make sense to set `position = "jitter"` for a bar chart. However, you could set `position = "dodge"` to create an unstacked bar chart.
Bar charts also use different position adjustments than scatterplots. It wouldn't make sense to set `position = "jitter"` for a bar chart. However, you could set `position = "dodge"` to create an unstacked bar chart. You'll learn about other position options in Section 2.
```{r}
ggplot(data = diamonds) +
geom_bar(mapping = aes(x = cut, fill = clarity), position = "dodge")
```
See Section 2 to learn about other position options.
#### Stats
Bar charts are interesting because they reveal something subtle about many types of plots. Consider our basic bar chart.
@ -289,12 +288,12 @@ 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.
* **bar charts** and **histograms** bin your data and then plot bin counts
* **smooth lines** (e.g. trend lines) apply a model to your data and then plot the model line
* **bar charts** and **histograms** bin your data and then plot bin counts, the number of points that fall in each bin.
* **smooth lines** (e.g. trend lines) apply 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 stat that it uses to plot your data. `geom_bar()` uses the "bin" stat, which bins raw data and computes bin counts. `geom_point()` uses the "identity" stat, which applies the identity transformation, i.e. no transformation.
`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 stat that it uses to plot your data. `geom_bar()` uses the "bin" stat, which bins raw data and computes bin counts. In contrast, `geom_point()` uses the "identity" stat, which applies the identity transformation, i.e. no transformation.
You can change the stat that your geom uses. For example, you can ask `geom_bar()` to use the "identity" stat. This is a useful way to plot data that already lists the heights for each bar, like the data set below.
@ -336,7 +335,7 @@ Answer: A coxcomb plot is a bar chart plotted in polar coordinates.
#### Coordinate systems
You can make coxcomb plots with `ggplot2` by first building a bar chart and then plotting it in polar coordinates.
You can make coxcomb plots with `ggplot2` by first building a bar chart and then plotting the chart in polar coordinates.
To plot your data in polar coordinates, 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.
@ -346,13 +345,15 @@ ggplot(data = diamonds) +
coord_polar()
```
You can add `coord_polar()` to any plot in `ggplot2` to draw the plot in polar coordinates. `ggplot2` will map the y variable to $r$ and your x variable to $\theta$.
You can add `coord_polar()` to any plot in `ggplot2` to draw the plot in polar coordinates. `ggplot2` will map your $y$ variable to $r$ and your $x$ variable to $\theta$.
#### Facets
Coxcomb plots are especially useful when you make many plots to compare against each other. Each coxcomb will act as a glyph that you can use to compare subgroups of data.
You can create a separate coxcomb plot for each subgroup in your data by _faceting_ your plot. For example, here we create a separate subplot for each level of the `clarity` variable.
You can create a separate coxcomb plot for each subgroup in your data by _faceting_ your plot. 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.
```{r fig.height = 7, fig.width = 7}
ggplot(data = diamonds) +
@ -361,10 +362,6 @@ ggplot(data = diamonds) +
facet_wrap( ~ clarity)
```
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.
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 `~`.
```{r fig.height = 7, fig.width = 7}
@ -374,9 +371,9 @@ ggplot(data = diamonds) +
facet_grid(color ~ clarity)
```
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. `facet_grid(color ~ clarity)` is not invoking the color aesthetic.
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.
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.
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) +
@ -386,8 +383,6 @@ ggplot(data = mpg) +
### Bringing it together
> "Wax on. Wax off."---*The Karate Kid* (1984)
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`.
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.
@ -407,59 +402,66 @@ The template takes seven parameters, the bracketed words that appear in the temp
The seven parameters in the template are connected by a powerful idea known as the _Grammar of Graphics_, a system for describing plots. The grammar shows 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.
Before we look at the grammar of graphics, let's take a look at the different choices that `ggplot2` offers for geoms, stats, position adjustments, coordinate systems, and facetting schemes.
Before we look at the grammar of graphics, let's take a look at the different geoms, stats, position adjustments, coordinate systems, and facetting schemes that you can use in `ggplot2`.
## The Vocabulary of `ggplot2`
`ggplot2` comes with 37 geom functions, 22 stats, eight coordinate systems, six position adjustments, two facetting schemes, and an uncounted number of aesthetics to map. Each of these components introduces new decisions for you to make and new dilemma's for you to consider.
`ggplot2` comes with 37 geom functions, 22 stats, eight coordinate systems, six position adjustments, two facetting schemes, and 28 aesthetics to map. Each of these options introduces a new set of details to think about.
Tackling these details can seem overwhelming to a new student, but you are ready. You understand the big picture that these details fits into, and you know how to make your own graphs, so you can try things out as you go.
This section will explain all of the options that you can use to make graphs with `ggplot2`. Read through this section once, then return to it as a reference guide when you need it.
This section will guide you through the options, building your ability to make new types of plots as you go. Let's begin with the most noticeable part of a data visualization, the geom.
### Geoms
The geom of a plot is the geometric object that the plot uses to represent its data. People often describe plots by the type of geom that they use. For example, bar charts use bar geoms, line charts use line geoms, boxplots use boxplot geoms, and so on.
The geom of a plot is the geometric object that the 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.
`ggplot2` provides 37 `geom_` functions that you can use to visualize your data. Each geom is particularly well suited for displaying a certain type of data or a certain type of relationship.
`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. You can loosely classify geoms into groups that:
This section organizes geoms according to these relationships. It describes each geom and lists the aesthetics to use with the geom.
1. Visualize distributions
2. Visualize functions between two variables
3. Visualize correlations between two variables
4. Visualize correlations between three variables
5. Visualize maps
6. Display basic objects (graphical primitives)
Throughout the section we will rely on an important distinction between two types of variables:
Let's examine each group one at a time. For all of the geoms in `ggplot2`, you use the geom by inserting the geom's function into the `<GEOM_FUNCTION>` spot in the code template in Section 1.
* A variable is **continuous** if you can arrange its values in order _and_ an infinite number of values exists between any two values of the variable.
***
Numbers and date-times are examples of continuous variables. `ggplot2` will treat your variable as continuous if it is a numeric, integer, or a recognizable date-time class (but not a factor, see `?factor`).
*Tip*: Throughout this section, we will rely on a distinction between two types of variables:
* A variable is **discrete** if it is not continuous. Discrete variables can only contain a finite (or countably infinite) set of unique values.
* A variable is **continuous** if you can arrange its values in order _and_ an infinite number of values can exist between any two values of the variable. For example, numbers and date-times are continuous variables. `ggplot2` will treat your variable as continuous if it is a numeric, integer, or a recognizable date-time class (but not a factor, see `?factor`).
Character strings and boolean values are examples of discrete data. `ggplot2` will treat your variable as discrete if it is not a numeric, integer, or recognizable date-time structure.
* A variable is **discrete** if it is not continuous. Discrete variables can only contain a finite (or countably infinite) set of unique values. For example, character strings and boolean values are discrete variables. `ggplot2` will treat your variable as discrete if it is not a numeric, integer, or recognizable date-time class.
***
#### Visualizing Distributions
Recall that a variable is a quantity, quality, or property whose value can change between measurements.
The first group of geoms visualizes the _distribution_ of the values in a variable.
This unique property---that the values of a variable can vary---gives the word "variable" its name. It also motivates all of data science. Scientists attempt to predict the value of variables and to understand what determines what those values will be.
Recall that a variable is a quantity, quality, or property whose value can change between measurements. This unique property---that the values of a variable can vary---gives the word "variable" its name. It also motivates all of data science. Scientists attempt to understand what determines the value of a variable. They then use that information to predict or control the value of the variable under a variety of circumstances.
One of the most useful tools in this quest are the values themselves. As you collect more data, the values of a variable will reveal which states of the variable are common, which are rare, and which are seemingly impossible. The pattern of the values that emerges is known as the variable's _distribution_.
One of the most useful tools in this quest are the values themselves, the values that you have already observed for a variable. These values reveal which states of the variable are common, which are rare, and which are seemingly impossible. The pattern of values that emerges as you collect large amounts of data is known as the variable's _distribution_.
The distribution of a variable reveals information about the probabilities associated with the variable. As you collect more data, the proportion of observations that occur at a value (or in an interval) will match the probability that the variable will take that value (or take a value in that interval) in a future measurement.
In theory, it is easy to visualize the distribution of a variable; simply display how many observations occur at each value of the variable. In practice, how you do this will depend on the type of variable that you wish to visualize.
##### Discrete distributions
To visualize the distribution of a discrete variable, count how many observations are associated with each value of the variable. You can compute these numbers quickly with R's `table()` function, but the easiest way to visualize the results is with `geom_bar()`.
```{r}
table(diamonds$cut)
```
##### `geom_bar()`
`geom_bar()` counts the number of observations that are associated with each value of a variable and displays the results as a bar. The height of each bar reveals the count of observations that are associated with the x value of the bar.
Use `geom_bar()` to visualize the distribution of a discrete variable. `geom_bar()` counts the number of observations that are associated with each value of the variable, and it displays the results as a series of bars. The height of each bar reveals the count of observations that are associated with the x value of the bar.
```{r}
ggplot(data = diamonds) +
geom_bar(mapping = aes(x = cut))
```
***
*Tip* - Since each of the geoms in this subsection visualizes the values of a single variable, you do not need to provide a $y$ aesthetic.
***
Useful aesthetics for `geom_bar()` are:
* x (required)
@ -476,71 +478,433 @@ Useful position adjustments for `geom_bar()` are
* "dodge"
* "fill"
Useful stats for `geom_bar()` are
* "bin" (default)
* "identity" (to map bar heights to a y variable)
The `width` argument of `geom_bar()` controls the width of each bar. The bars will touch when you set `width = 1`.
```{r}
ggplot(data = diamonds) +
geom_bar(mapping = aes(x = cut), width = 1)
```
***
*Tip*: You can compute the counts of a discrete variable quickly with R's `table()` function. These are the numbers that `geom_bar()` visualizes.
```{r}
table(diamonds$cut)
```
***
##### Continuous distributions
Plotting the distribution of a continuous variable is more tricky than plotting the distribution of a discrete variable.
The strategy of counting the number of observations at each value breaks down for continuous data. If your data is truly continuous, then no two observations will have the same value---so long as you measure the data precisely enough (e.g. without rounding to the _n_th decimal place).
To reveal the distribution, you must first _bin_ the range of the variable, which means to divide the range into equally spaced intervals.
To get around this, data scientists divide the range of a continuous variable into equally spaced intervals, a process called _binning_.
`r bookdown::embed_png("images/blank.png", dpi = 150)`
`r bookdown::embed_png("images/visualization-17.png", dpi = 150)`
You can then count the number of observations that fall into each bin.
They then count how many observations fall into each bin.
`r bookdown::embed_png("images/blank.png", dpi = 150)`
`r bookdown::embed_png("images/visualization-18.png", dpi = 150)`
And display them as a bar, or some other object.
And display the count as a bar, or some other object.
`r bookdown::embed_png("images/blank.png", dpi = 150)`
`r bookdown::embed_png("images/visualization-19.png", dpi = 150)`
This method is temperamental because the appearance of the distribution can change dramatically if the bin size changes. As no bin size is "correct," you should explore several bin sizes when examining data.
Several geoms exist to help you, and they almost all use the "bin" stat to implement the above strategy. For each of these geoms, you can set the following arguments for "bin" to use:
`r bookdown::embed_png("images/visualization-20.png", dpi = 150)`
* binwidth - the width to use for the bins in the same units as the x variable
* origin - origin of the first bin interval
* right - if `TRUE` bins will be right closed (e.g. points that fall on the border of two bins will be counted with the bin to the left)
* breaks - a vector of actual bin breaks to use. If you set the breaks argument, it will overide the binwidth and origin arguments.
Several geoms exist to help you visualize continuous distributions. They almost all use the "bin" stat to implement the above strategy. For each of these geoms, you can set the following arguments for "bin" to use:
###### Histograms
###### Freqpoly
###### Dotplots
###### Density
###### Boxplots
##### Bivariate Distributions
###### bin2d
###### hex
###### density2d
###### rug
#### Visualizing Relationships
##### Discrete x, discrete y
###### Jitter
##### Discrete x, continuous y
###### Bar Charts
###### Boxplots
###### Dotplots
###### Violin plots
###### crossbar
###### errorbar
###### linerange
###### point range
##### Continuous x, continuous y
###### Points
###### Text
###### Jitter
###### Smooth
###### Quantile
##### Functions
###### line
###### area
###### step
##### Discrete x, discrete y, continuous z
###### raster
###### tile
##### Continuous x, continuous y, continuous z
###### contour
##### Maps
* `binwidth` - the width to use for the bins in the same units as the x variable
* `origin` - origin of the first bin interval
* `right` - if `TRUE` bins will be right closed (e.g. points that fall on the border of two bins will be counted with the bin to the left)
* `breaks` - a vector of actual bin breaks to use. If you set the breaks argument, it will overide the binwidth and origin arguments.
### Mappings
Use `geom_histogram()` to make a traditional histogram. The height of each bar reveals how many observations fall within the width of the bar.
```{r}
ggplot(data = diamonds) +
geom_histogram(aes(x = carat))
```
By default, `geom_histogram()` will divide the range of the variable into 30 equal length bins. The quickest way to change this behavior is to set the binwidth argument.
```{r}
ggplot(data = diamonds) +
geom_histogram(aes(x = carat), binwidth = 1)
```
Notice how different binwidths reveal different information. The plot above shows that the availability of diamonds decreases quickly as carat size increases. The plot below shows that there are more diamonds than you would expect at whole carat sizes (and common fractions of carat sizes). Moreover, for each popular size, there are more diamonds that are slightly larger than the size than there are that are slightly smaller than the size.
```{r}
ggplot(data = diamonds) +
geom_histogram(aes(x = carat), binwidth = 0.01)
```
Useful aesthetics for `geom_histogram()` are:
* x (required)
* alpha
* color
* fill
* linetype
* size
* weight
Useful position adjustments for `geom_histogram()` are
* "stack" (default)
* "fill"
`geom_freqpoly()` uses a line to display the same information as `geom_histogram()`. You can think of `geom_freqpoly()` as drawing a line that connects the tops of the bars that would appear in a histogram.
```{r message = FALSE, fig.show='hold', fig.width=4, fig.height=4}
ggplot(data = diamonds) +
geom_freqpoly(aes(x = carat))
ggplot(data = diamonds) +
geom_histogram(aes(x = carat))
```
It is easier to compare levels of a third variable with `geom_freqpoly()` than with `geom_histogram()`. `geom_freqpoly()` displays the shape of the distribution faithfully for each subgroup because you can plot multiple lines in the same graph without adjusting their position. Notice that `geom_histogram()` must stack each new subgroup on top of the others, which obscures the shape of the distributions.
```{r message = FALSE, fig.show='hold', fig.width=4, fig.height=4}
ggplot(data = diamonds) +
geom_freqpoly(aes(x = carat, color = cut))
ggplot(data = diamonds) +
geom_histogram(aes(x = carat, fill = cut))
```
Useful aesthetics for `geom_freqpoly()` are:
* x (required)
* y
* alpha
* color
* linetype
* size
Although the name of `geom_freqpoly()` suggests that it draws a polygon, it actually draws a line. You can draw the same information as a true polygon (and thus fill in the area below the line) if you combine `geom_area()` with `stat = "bin"`. You will learn more about `geom_area()` in _Visualizing functions between two variables_.
```{r}
ggplot(data = diamonds) +
geom_area(aes(x = carat, fill = cut), stat = "bin", position = "stack")
```
`geom_density()` plots a one dimensional kernel density estimate of a variable's distribution. The result is a smooth version of the information contained in a histogram or a freqpoly.
```{r}
ggplot(data = diamonds) +
geom_density(aes(x = carat))
```
`geom_density()` displays $density$---not $count$---on the y axis, which makes it easier to compare the shape of the distributions of multiple subgroups; the area under each curve will be normalized to one, no matter how many total observations occur in the subgroup.
`geom_density()` does not use the binwidth argument. You can control the smoothness of the density with `adjust`, and you can select the kernel to use to estimate the density with `kernel`. Set kernel to one of "gaussian" (default), "epanechikov", "rectangular", "triangular", "biweight", "cosine", "optcosine".
```{r}
ggplot(data = diamonds) +
geom_density(aes(x = carat, color = cut), kernel = "gaussian", adjust = 4)
```
Useful aesthetics for `geom_density()` are:
* x (required)
* y
* alpha
* color
* fill
* linetype
* size
Useful position adjustments for `geom_density()` are
* "identity" (default)
* "stack" (when using the fill aesthetic)
* "fill" (when using the fill aesthetic)
`geom_dotplot()` provides a final way to visualize distributions. This unique geom displays a point for each observation, but it stacks points that appear in the same bin on top of each other. The result is similar to a histogram, the height of each stack reveals the number of points in the stack.
```{r}
ggplot(data = mpg) +
geom_dotplot(aes(x = displ), binwidth = 0.2)
```
Useful aesthetics for `geom_dotplot()` are:
* x (required)
* y
* alpha
* color
* fill
Useful arguments that apply to `geom_dotplot()`
* `binaxis` - the axis to bin along ("x" or "y")
* `binwidth` - the interval width to use when binning
* `dotsize` - diameter of dots relative to binwidth
* `stackdir` - which direction to stack the dots ("up" (default), "down", "center", "centerwhole")
* `stackgroups` - Has the equivalent of `position = "stack"` when set to true.
* `stackratio` - how close to stack the dots. Values less than 1 cause dots to overlap, which shortens stacks.
In practice, I find that `geom_dotplot()` works best with small data sets and takes a lot of tweaking of the binwidth, dotsize, and stackratio arguments to fit the dots within the graph (the stack heights depend entirely on the organization of the dots, which renders the y axis ambiguous). That said, dotplots can be useful as a learning aid. They provide an intuitive representation of a histogram.
#### Visualize functions between two variables
Distributions provide useful information about variables, but the information is general. By itself, a distribution cannot tell you how the value of a variable in one set of circumstances will differ from the value of the same variable in a different set of circumstances.
_Covariation_ can provide more specific information. Covariation is a relationship between the values of two or more variables.
To see how covariation works, consider two variables: the $volume$ of an object and its $temperature$. If the $volume$ of the object usually increases when the $temperature$ of the object increases, then you could use the value of $temperature$ to help predict the value of $volume$.
You've probably heard that "correlation (covariation) does not prove causation." This is true, two variables can covary without one causing the other. However, covariation is often the first clue that two variables have a causal relationship.
Visualization is one of the best ways to spot covariation. How you look for covariation will depend on the structural relationship between two variables. The simplest structure occurs when two continuous variables have a functional relationship, where each value of one variable corresponds to a single value of the second variable.
In this scenario, covariation will appear as a pattern in the relationship. If two variables o not covary, their functional relationship will look like a random walk.
The variables `date` and `unemploy` in the `economics` data set have a functional relationship. The `economics` data set comes with `ggplot2` and contains various economic indicators for the United States between 1967 and 2007. The `unemploy` variable measures the number of unemployed individuals in the United States in thousands.
A scatterplot of the data reveals the functional relationship between `date` and `unemploy`.
```{r}
ggplot(data = economics) +
geom_point(aes(x = date, y = unemploy))
```
`geom_line()` makes the relationship clear. `geom_line()` creates a line chart, one of the most used---and most efficient---devices for visualizing a function.
```{r}
ggplot(data = economics) +
geom_line(aes(x = date, y = unemploy))
```
Useful aesthetics for `geom_line()` are:
* x (required)
* y (required)
* alpha
* color
* linetype
* size
Use `geom_step()` to turn a line chart into a step function. Here, the result will be easier to see with a subset of data.
```{r}
ggplot(data = economics[1:150, ]) +
geom_step(aes(x = date, y = unemploy))
```
Control the step direction by giving `geom_step()` a direction argument. `direction = "hv"` will make stairs that move horizontally then vertically to connect points. `direction = "vh"` will do the opposite.
Useful aesthetics for `geom_step()` are:
* x (required)
* y (required)
* alpha
* color
* linetype
* size
`geom_area()` creates a line chart with a filled area under the line.
```{r}
ggplot(data = economics) +
geom_area(aes(x = date, y = unemploy))
```
Useful aesthetics for `geom_area()` are:
* x (required)
* y (required)
* alpha
* color
* fill
* linetype
* size
##### Visualize correlations between two variables
Many variables do not have a functional relationship. As a result, a single value of one variable can correspond to multiple values of another variable.
Height and weight are two variables that are often related, but do not have a functional relationship. You could examine a classroom of students and notice that three different students, with three different weights all have the same height, 5'4". In this case, there is not a one to one relationship between height and weight.
The easiest way to plot the relationship between two variables is with a scatterplot, i.e. `geom_point()`. If the variables covary, a pattern will appear in the points. If they do not, the points will look like a random cloud of points.
```{r}
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy))
```
Useful aesthetics for `geom_point()` are:
* x (required)
* y (required)
* alpha
* color
* fill (for some shapes)
* shape
* size
Useful position adjustments for `geom_point()` are:
* "identity" (default)
* "jitter"
In fact, the jitter adjustment is so useful that `ggplot2` provides the `geom_jitter()`, which is identical to `geom_point()` but comes with `position = "jitter"` by default.
```{r}
ggplot(data = mpg) +
geom_jitter(mapping = aes(x = displ, y = hwy))
```
`geom_jitter()` can be a useful way to visualize the distribution between two discrete variables. Can you tell why `geom_point()` would be less useful here?
```{r}
ggplot(data = mpg) +
geom_jitter(mapping = aes(x = cyl, y = fl, color = fl))
```
Use `geom_rug()` to visualize the distribution of each variable in the scatterplot. `geom_rug()` adds a tickmark along each axis for each value observed in the data. `geom_rug()` works best as a second layer in the plot (see Section 3 for more info on layers).
```{r}
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy)) +
geom_rug(mapping = aes(x = displ, y = hwy), position = "jitter")
```
Use the `sides` argument to control which axes to place a "rug" on.
* `sides = "bl"` - (default) Places a rug on each axis
* `sides = "b"` - Places a rug on the bottom axis
* `sides = "l"` - Places a rug on the left axis
Useful aesthetics for `geom_rug()` are:
* x (required)
* y (required)
* alpha
* color
* linetype
* size
Useful position adjustments for `geom_rug()` are:
* "identity" (default)
* "jitter"
Use `geom_text()` to display a label, instead of a point, for each observation in a scatterplot. `geom_text()` lets you add information to the scatterplot, but is less effective when you have many data points.
```{r}
ggplot(data = mpg[sample(1:234, 10), ]) +
geom_text(mapping = aes(x = displ, y = hwy, label = class))
```
Useful aesthetics for `geom_text()` are:
* x (required)
* y (required)
* alpha
* angle
* color
* family
* fontface
* hjust
* label (`geom_text()` displays the values of this variable)
* lineheight
* linetype
* size
* vjust
Control the appearance of the labels with the following arguments. You can also use each of these arguments as an aesthetic. To do so, set them inside the `aes()` call in `geom_text()`'s mapping argument.
* `angle` - angle of text
* `family` - font family of text
* `fontface` - bold, italic, etc.
* `hjust` - horizontal adjustment
* `vjust`- vertical adjustment
Scatterplots do not work well with large data sets because individual points will begin to occlude each other. As a result, you cannot tell where the mass of the data lies. Does a black region contain a single layer of points? Or hundreds of points stacked on top of each other.
You can see this type of plotting in the `diamonds` data set. The data set only contains 53,940 points, but the points overplot each other in a way that we cannot fix with jittering.
```{r}
ggplot(data = diamonds) +
geom_point(mapping = aes(x = carat, y = price))
```
For large data, it is more useful to plot summary information that describes the raw data than it is to plot the raw data itself. Several geoms can help you do this.
The simplest way to summarize covariance between two variables is with a model line. The model line displays the trend of the relationship between the variables.
Use `geom_smooth()` to display a model line between any two variables. As with `geom_rug()`, `geom_smooth()` works well as a second layer for a plot (See Section 3 for details).
```{r}
ggplot(data = diamonds) +
geom_point(mapping = aes(x = carat, y = price)) +
geom_smooth(mapping = aes(x = carat, y = price))
```
`geom_smooth()` will add a loess line to your data if the data contains less than 1000 points, otherwise it will fit a general additive model to your data with a cubic regression spline, and plot the resulting model line. In either case, `geom_smooth()` will display a message in the console to tell you what it is doing. This is not a warning message; you do not need to worry when you see it.
`geom_smooth()` will also plot a standard error band around the model line. You can remove the standard error band by setting the `se` argument of `geom_smooth()` to `FALSE`.
Use the `model` argument of `geom_smooth()` to adda specific type of model line to your data. `model` takes the name of an R modeling function. `geom_smooth()` will use the function to calculate the model line. For example, the code below uses R's `lm()` function to fit a linear model line to the data.
```{r}
ggplot(data = diamonds) +
geom_point(mapping = aes(x = carat, y = price)) +
geom_smooth(mapping = aes(x = carat, y = price), method = lm)
```
By default, `geom_smooth()` will use the formula `y ~ x` to model your data. You can modify this formula by setting the `formula` argument to a different formula. If you do this, be sure to refer to the variable on your $x$ axis as `x` and the variable on your $y$ axis as `y`, e.g.
```{r}
ggplot(data = diamonds) +
geom_point(mapping = aes(x = carat, y = price)) +
geom_smooth(mapping = aes(x = carat, y = price),
method = lm, formula = y ~ poly(x, 4))
```
Useful aesthetics for `geom_smooth()` are:
* x (required)
* y (required)
* alpha
* color
* fill
* linetype
* size
* weight
Useful arguments for `geom_smooth()` are:
* `formula` - the formula to use in the smoothing function
* `fullrange` - Should the fit span the full range of the plot, or just the data?
* `level` - Confidence level to use for standard error ribbon
* `method` - Smoothing function to use, a model function in R
* `n` - The number of points to evaluate smoother at (defaults to 80)
* `se` - If TRUE` (the default), `geom_smooth()` will include a standard error ribbon
Be careful, `geom_smooth()` will overlay a trend line on every data set, even if the underlying data is uncorrelated. You can avoid being fooled by also inspecting the raw data or calculating the correlation between your variables, e.g. `cor(diamonds$carat, diamonds$price)`.
##### Visualize correlations between three variables
##### Visualize maps
##### Display basic objects (graphical primitives)
#### Aesthetic Mappings
Have you experimented with aesthetics? Great! Here are some things that you may have noticed.