---
title: "ggrepel Usage Examples"
author: "Kamil Slowikowski"
date: "`r Sys.Date()`"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{ggrepel Usage Examples}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r setup, echo=FALSE, results='hide', warning=FALSE, error=FALSE, message=FALSE, cache=FALSE}
library(knitr)
opts_chunk$set(
  cache = TRUE,
  autodep = TRUE,
  echo = FALSE,
  warning = FALSE,
  error = FALSE,
  message = FALSE,
  out.width = 700,
  fig.width = 12,
  fig.height = 8,
  dpi = 144,
  cache.path = "cache/ggrepel/",
  fig.path = "figures/ggrepel/",
  concordance = TRUE
)
```

# ggrepel

## Motivation

Some text labels overlap each other in plots created with [geom_text]:

```{r geom_text, echo=TRUE}
library(ggplot2)
ggplot(mtcars) +
  geom_point(aes(wt, mpg), color = 'red') +
  geom_text(aes(wt, mpg, label = rownames(mtcars))) +
  theme_classic(base_size = 16)
```

## Algorithm

`ggrepel` implements functions to repel overlapping text labels away from
each other and away from the data points that they label. The algorithm
works as follows:

- For each box:
    - Move the box into the allowed plotting area.
    - If the bounding box overlaps other boxes:
        - Repel the overlapping boxes from each other.
    - If the bounding box overlaps data points:
        - Repel the box away from the data points.
- Repeat until all overlaps are resolved, up to a preset limit
  of iterations.

## Usage Examples

### geom_text_repel

We can repel the text labels away from each other by loading `ggrepel` and
using `geom_text_repel` instead:

```{r geom_text_repel, echo=TRUE}
library(ggrepel)
set.seed(42)
ggplot(mtcars) +
  geom_point(aes(wt, mpg), color = 'red') +
  geom_text_repel(aes(wt, mpg, label = rownames(mtcars))) +
  theme_classic(base_size = 16)
```

#### Options

All options available for [geom_text] such as `size` and
`fontface` are also available for `geom_text_repel`.

However, the following parameters are not supported:

- `hjust`
- `vjust`
- `position`
- `check_overlap`

`ggrepel` provides additional parameters for `geom_text_repel` and `geom_label_repel`:

- `segment.color` is the line segment color
- `box.padding` is the padding surrounding the text bounding box
- `point.padding` is the padding around the labeled point
- `arrow` is the specification for arrow heads created by `grid::arrow`
- `force` is the force of repulsion between overlapping text labels
- `max.iter` is the maximum number of iterations to attempt to resolve overlaps
- `nudge_x` is how much to shift the starting position of the text label along
  the x axis
- `nudge_x` is how much to shift the starting position of the text label along
  the y axis

```{r geom_text_repel_options, echo=TRUE}
set.seed(42)
ggplot(mtcars) +
  geom_point(aes(wt, mpg), color = 'grey', size = 4, shape = 15) +
  geom_text_repel(
    aes(
      wt, mpg,
      color = factor(cyl),
      label = rownames(mtcars)
    ),
    size = 5,
    fontface = 'bold',
    box.padding = unit(0.5, 'lines'),
    point.padding = unit(1.6, 'lines'),
    segment.color = '#555555',
    segment.size = 0.5,
    arrow = arrow(length = unit(0.01, 'npc')),
    force = 1,
    max.iter = 2e3,
    nudge_x = ifelse(mtcars$cyl == 6, 1, 0),
    nudge_y = ifelse(mtcars$cyl == 6, 8, 0)
  ) +
  scale_color_discrete(name = 'cyl') +
  theme_classic(base_size = 16)
```

### geom_label_repel

`geom_label_repel` is based on [geom_label].

```{r geom_label_repel, echo=TRUE}
set.seed(42)
ggplot(mtcars) +
  geom_point(aes(wt, mpg), size = 5, color = 'grey') +
  geom_label_repel(
    aes(wt, mpg, fill = factor(cyl), label = rownames(mtcars)),
    fontface = 'bold', color = 'white',
    box.padding = unit(0.25, "lines"),
    point.padding = unit(0.5, "lines")
  ) +
  theme_classic(base_size = 16)
```

### Line plot

```{r line_plot, echo=TRUE}
set.seed(42)
ggplot(Orange, aes(age, circumference, color = Tree)) +
  geom_line() +
  coord_cartesian(xlim = c(min(Orange$age), max(Orange$age) + 90)) +
  geom_text_repel(
    data = subset(Orange, age == max(age)),
    aes(label = paste("Tree", Tree)),
    size = 6,
    nudge_x = 45,
    segment.color = NA
  ) +
  theme_classic(base_size = 16) +
  theme(legend.position = "none") +
  labs(x = "Age (days)", y = "Circumference (mm)")
```

### Volcano plot

```{r volcano, echo=TRUE}
set.seed(42)

# Read Stephen Turner's data
genes <- read.table("genes.txt.bz2", header = TRUE)
genes$Significant <- ifelse(genes$padj < 0.05, "FDR < 0.05", "Not Sig")

ggplot(genes, aes(x = log2FoldChange, y = -log10(pvalue))) +
  geom_point(aes(color = Significant)) +
  scale_color_manual(values = c("red", "grey")) +
  theme_bw(base_size = 16) +
  geom_text_repel(
    data = subset(genes, padj < 0.05),
    aes(label = Gene),
    size = 5,
    box.padding = unit(0.35, "lines"),
    point.padding = unit(0.3, "lines")
  )
```

### Animation

```{r animated, echo=TRUE, eval=FALSE}
# This chunk of code will take a minute or two to run.
library(ggrepel)
library(animation)

plot_frame <- function(n) {
  set.seed(42)
  p <- ggplot(mtcars) +
    geom_point(aes(wt, mpg), color = 'red') +
    geom_text_repel(
      aes(wt, mpg, label = rownames(mtcars)),
      size = 5, force = 3, max.iter = n
    ) +
    theme_classic(base_size = 16)
  print(p)
}

saveGIF(
  lapply(c(seq(0, 2000, 25)), function(i) {
    plot_frame(i)
  }),
  interval = 0.05,
  ani.width = 800,
  ani.heigth = 600,
  movie.name = 'animated.gif'
)
```

<img src="figures/ggrepel/animated.gif" title="animation"
  alt="animation of geom_repel_text" width="700"/>

## R Session Info

```{r session_info, echo=TRUE}
sessionInfo()
```

[geom_text]: http://docs.ggplot2.org/current/geom_text.html
[geom_label]: http://docs.ggplot2.org/current/geom_text.html
