Reference lines, segments, curves and arrows in ggplot2

The ggplot2 package has several functions to add annotation layers to the plots such as reference lines (geom_vline, geom_hline and geom_abline), segments (geom_segment), curves (geom_curve) and arrows (arrows). In this tutorial we are going to review the most common use cases of these functions.

Vertical lines with geom_vline

Considering that you have a plot made with ggplot2 you can add a new layer with geom_vline to add a single or multiple vertical lines. You just need to pass a single value or a numeric vector to the xintercept argument of the function where you want the lines to be displayed.

Note that you can also customize graphical arguments such as linetype, color or lwd.

# install.packages("ggplot2")
library(ggplot2)

# Data
set.seed(1)
df <- data.frame(x = rnorm(100),
                 y = rnorm(100))

ggplot(df, aes(x = x, y = y)) +
  geom_point() +
  geom_vline(xintercept = 0,
             linetype = 2,
             color = 2)

Vertical line in ggplot2 with geom_vline

Adding several lines at once

Note that all functions of this tutorial allow doing this.

# install.packages("ggplot2")
library(ggplot2)

# Data
set.seed(1)
df <- data.frame(x = rnorm(100),
                 y = rnorm(100))

ggplot(df, aes(x = x, y = y)) +
  geom_point() +
  geom_vline(xintercept = -1:1,
             linetype = 1,
             color = 2:4)

Adding multiple vertical lines in ggplot2 with geom_vline

Horizontal lines with geom_hline

The geom_hline function behaves the same way as geom_vline. The only difference is that this function will add horizontal lines, so you will need to specify the yintercept argument instead of xintercept.

Horizontal lines in ggplot2 with geom_hline

# install.packages("ggplot2")
library(ggplot2)

# Data
set.seed(1)
df <- data.frame(x = rnorm(100),
                 y = rnorm(100))

ggplot(df, aes(x = x, y = y)) +
  geom_point() +
  geom_hline(yintercept = -1:1,
             linetype = 3,
             color = 4,
             lwd = 1)

Diagonal lines with geom_abline

The geom_abline function allows adding diagonal lines based on a intercept and a slope. The following example shows a diagonal line with intercept 0 and slope of 1.

# install.packages("ggplot2")
library(ggplot2)

# Data
set.seed(1)
df <- data.frame(x = rnorm(100),
                 y = rnorm(100))

ggplot(df, aes(x = x, y = y)) +
  geom_point() +
  geom_abline(intercept = 0,
              slope = 1)

Adding a diagonal line in ggplot2 with geom_abline

Segments with geom_segment

The previous functions can be used to add lines to the plots, but you cannot create segments with them. For that reason there exists the geom_segment function, which allows specifying the X and Y coordinates of the start and end of the desired segment with x, y (start) and xend, yend (end), respectively.

Note that if you pass the arrow function to the arrow argument you can create an arrow. See the arguments of the arrow function for further customization.

Adding segments in ggplot2 with geom_segment

# install.packages("ggplot2")
library(ggplot2)

# Data
set.seed(1)
df <- data.frame(x = rnorm(100),
                 y = rnorm(100))

ggplot(df, aes(x = x, y = y)) +
  geom_point() +
  geom_segment(x = -1, y = 0,
               xend = 1, yend = 1,
               color = 2)

Adding an arrow to ggplot2 with geom_segment and the arrow function

Annotate arrow

# install.packages("ggplot2")
library(ggplot2)

# Data
set.seed(1)
df <- data.frame(x = rnorm(100),
                 y = rnorm(100))

ggplot(df, aes(x = x, y = y)) +
  geom_point() +
  geom_segment(x = -2, y = 1,
               xend = 1, yend = -1,
               color = 2,
               arrow = arrow())

Curves with geom_curve

The geom_curve function behaves the same way as geom_segment. The only difference is that this function will create a curve instead of a straight line. You can also create an arrow using this function.

# install.packages("ggplot2")
library(ggplot2)

# Data
set.seed(1)
df <- data.frame(x = rnorm(100),
                 y = rnorm(100))

ggplot(df, aes(x = x, y = y)) +
  geom_point() +
  geom_curve(x = -2, y = 1,
             xend = 1, yend = -1,
             color = 4)

Adding a curve to ggplot2 with geom_curve

Note that you can set the level of curvature passing a value the curvature argument of the function. A zero is a straight line, negative values will produce left-handed curves and positive values produce right-handed curves.

# install.packages("ggplot2")
library(ggplot2)

# Data
set.seed(1)
df <- data.frame(x = rnorm(100),
                 y = rnorm(100))

ggplot(df, aes(x = x, y = y)) +
  geom_point() +
  geom_curve(x = -2, y = 1,
             xend = 1, yend = -1,
             color = 4,
             curvature = -0.2) # Level of curvature

Changing the level of curvature of the ggplot2 curve annotation

Annotate arrow

# install.packages("ggplot2")
library(ggplot2)

# Data
set.seed(1)
df <- data.frame(x = rnorm(100),
                 y = rnorm(100))

ggplot(df, aes(x = x, y = y)) +
  geom_point() +
  geom_curve(x = -2, y = 1,
             xend = 1, yend = -1,
             color = 2,
             arrow = arrow())

Curved arrow in ggplot2

Storytelling with Data

A Data Visualization Guide for Business Professionals

Buy on Amazon
Better Data Visualizations

A Guide for Scholars, Researchers, and Wonks

Buy on Amazon
Fundamentals of Data Visualization

A Primer on Making Informative and Compelling Figures

Buy on Amazon

See also