Custom scales in ggplot2
   get_help() docs


Description

All functions documented here are part of the {ggplot2} package, which is part of the {tidyverse}.

The {ggplot2} package provides several useful functions (and see here) for creating your own aesthetic mapping scales. With these functions, you can manually customize how colors, fills, shapes, sizes, alpha (transparency), and and linetypes are mapped to your data. You should only use these functions when you have MAPPED an aesthetic. If you are trying to specify a color, fill, shape, etc. directly without any mapping, simply provide the argument to the geom of interest.

All functions are named scale_AESTHETIC-TYPE_manual() (except for those ending in gradient() or gradient2(), which are used for continuous mappings), where AESTHETIC-TYPE is a type of aesthetic mapping you have specified. These functions include:

Function Specify custom mapping of…
scale_color_manual() (aka scale_colour_manual()) Discrete/categorical colors
scale_fill_manual() Discrete/categorical fills
scale_color_gradient() (aka scale_colour_gradient()) Continuous gradient colors
scale_color_gradient2() (aka scale_colour_gradient2()) Continuous gradient2 colors
scale_fill_gradient() Continuous gradient fills
scale_fill_gradient2() Continuous gradient2 fills
scale_shape_manual() Shapes
scale_alpha_manual() Alpha (transparency) level
scale_size_manual() Sizes (This is generally not recommended unless you really know what you’re doing, since it is easy to distort sizes and make interpretation difficult)
scale_linetype_manual() Linetypes

For more information about color and fill scales specifically, either…

To use these functions, you need to either first load the {ggplot2} library, or always use the function with ggplot2::() notation.

# Load the library
library(ggplot2)
# Or, load the full tidyverse:
library(tidyverse)

# Or, use :: notation, for example with scale_color_manual()
ggplot2::scale_color_manual()

Conceptual Usage

# Basic usage of non-gradient functions:
scale_AESTHETIC-TYPE_manual(values = c(array, of, values, to, use, for, mapping))

scale_AESTHETIC-TYPE_manual(values = c(array, of, values, to, use, for, mapping),
                            na.value = specify value to use for data mapping to NA)

# Note that the legend name can be specified here or with `ggplot2::labs()`
scale_AESTHETIC-TYPE_manual(name = Name of legend associated with this mapping,
                            values = c(array, of, values, to, use, for, mapping))

# Basic usage of color/fill gradient functions:
scale_AESTHETIC-TYPE_gradient(low = 'low color', high = 'high color')
scale_AESTHETIC-TYPE_gradient2(low = 'low color', 
                               high = 'high color', 
                               mid = 'midpoint color', 
                               midpoint = 'midpoint value where gradient switches')

Examples

The examples below use the msleep dataset. Learn more about this dataset with get_help("msleep").

# Show the msleep dataset with head()
head(msleep)
## # A tibble: 6 × 11
##   name  genus vore  order conservation sleep_total sleep_rem sleep_cycle awake  brainwt  bodywt
##   <chr> <chr> <chr> <chr> <chr>              <dbl>     <dbl>       <dbl> <dbl>    <dbl>   <dbl>
## 1 Owl … Aotus omni  Prim… <NA>                17         1.8      NA       7    0.0155    0.48 
## 2 Moun… Aplo… herbi Rode… nt                  14.4       2.4      NA       9.6 NA         1.35 
## 3 Grea… Blar… omni  Sori… lc                  14.9       2.3       0.133   9.1  0.00029   0.019
## 4 Cow   Bos   herbi Arti… domesticated         4         0.7       0.667  20    0.423   600    
## 5 Thre… Brad… herbi Pilo… <NA>                14.4       2.2       0.767   9.6 NA         3.85 
## 6 Nort… Call… carni Carn… vu                   8.7       1.4       0.383  15.3 NA        20.5


# Specify custom colors for the `vore` color mapping, ensuring the number of values MATCHES the number of vores (except NAs)
ggplot(msleep) + 
  aes(x = sleep_rem, 
      y = awake, 
      color = vore) + 
  geom_point() +
  scale_color_manual(
    # There are 4 vores, so we need 4 colors
    values = c("blue", "red", "orange", "pink")
  )


# Specify custom colors for the `vore` color mapping, ensuring the number of values MATCHES the number of vores (except NAs)
# This time, use the `name` argument for a customized legend title
ggplot(msleep) + 
  aes(x = sleep_rem, 
      y = awake, 
      color = vore) + 
  geom_point() +
  scale_color_manual(
    name = "Customized new legend title",
    # There are 4 vores, so we need 4 colors
    values = c("blue", "red", "orange", "pink")
  )


# Instead of the previous example, you can also `labs()` to specify the legend title 
ggplot(msleep) + 
  aes(x = sleep_rem, 
      y = awake, 
      color = vore) + 
  geom_point() +
  scale_color_manual( values = c("blue", "red", "orange", "pink")) + 
  labs(color = "Customized new legend title")


# To customize the color used for NA values, use the argument `na.value`
ggplot(msleep) + 
  aes(x = sleep_rem, 
      y = awake, 
      color = vore) + 
  geom_point() +
  scale_color_manual(
    values = c("blue", "red", "orange", "pink"),
    na.value = "yellow" # Now all vore that are NA will be yellow instead of the default dark gray
  )


# The values are applied in the order values appear on the axis
# If you change the order with forcats, colors get applied in the new order
# Again, when using forcats, it's best practice to clean up the legend title
ggplot(msleep) + 
  aes(x = sleep_rem, 
      y = awake, 
      # For example, reverse the order of vore in the plot
      color = forcats::fct_rev(vore)) + 
  geom_point() +
  scale_color_manual(
    name = "vore", # Adding legend title to clean up after forcats usage
    values = c("blue", "red", "orange", "pink"),
    na.value = "yellow" # Now all vore that are NA will be yellow instead of the default dark gray
  )


# CAUTION!! If you don't include an aesthetic in the first place, none of your manual values appear
ggplot(msleep) + 
  aes(x = sleep_rem, 
      y = awake) + # forgetting the color = vore means no colors and no legend show up 
  geom_point() +
  scale_color_manual(values = c("blue", "red", "orange", "pink"))



# Use a custom gradient mapping, suitable since we are now coloring by `awake`, a continuous variable
ggplot(msleep) + 
  aes(x = sleep_rem, 
      y = awake, 
      color = awake) +  # Color by continuous variable awake
  geom_point() +
  scale_color_gradient(
    low = "blue",
    high = "orange"
  )


# Use a custom gradient2 mapping, suitable since we are now coloring by `awake`, a continuous variable
ggplot(msleep) + 
  aes(x = sleep_rem, 
      y = awake, 
      color = awake) +  # Color by continuous variable awake
  geom_point() +
  scale_color_gradient2(
    low = "blue",
    mid = "black",
    high = "orange",
    midpoint = 14 # switch from blue->black->orange at awake (the mapped variable) = 14
  )


# Use a custom gradient mapping, suitable since we are now FILLING by `awake`, a continuous variable
# This time use pch = 21 to get a fillable point
ggplot(msleep) + 
  aes(x = sleep_rem, 
      y = awake, 
      fill = awake) +  # FILL by continuous variable awake
  geom_point() +
  scale_fill_gradient2(
    low = "blue",
    high = "orange"
  )


# Specify custom shapes for the `vore` shape mapping
# Use `get_help("geom_point")` to see different types of shapes in R plotting
ggplot(msleep) + 
  aes(x = sleep_rem, 
      y = awake, 
      shape = vore) + 
  geom_point() +
  scale_shape_manual(
    values = c(1, 2, 3, 4), # There are 4 vores, so we need 4 shapes
    na.value = 19 # optionally, specify a shape for the NAs
  )


# Specify custom fills for the `vore` fill mapping
ggplot(msleep) + 
  aes(x = vore, 
      y = awake, 
      fill = vore) + 
  geom_boxplot() +
  scale_fill_manual(
    values = c("blue", "red", "orange", "pink"),
    na.value = "yellow" 
  )


# CAUTION!! If you specify a fill aesthetic but you don't use scale_FILL_manual, it won't work
# Instead, resulting fills will be _the default fills_
ggplot(msleep) + 
  aes(x = vore, 
      y = awake, 
      fill = vore) + 
  geom_boxplot() +
  # Accidentally applying a manual color scale doesn't change the plot, since a FILL aesthetic was used
  scale_color_manual(
    values = c("blue", "red", "orange", "pink"),
    na.value = "yellow" 
  )


# Specify custom alphas for the vore alpha mapping
# We also include a fill aesthetic to vore so that we have fills to make transparent
ggplot(msleep) + 
  aes(x = vore, 
      y = awake, 
      alpha = vore, 
      fill = vore) + 
  geom_boxplot() +
  scale_alpha_manual(
    # alpha can range from 0-1. Notice how fills become increasingly opaque
    values = c(0.2, 0.4, 0.6, 0.8),
    na.value = 1
  )


# Create a dataset over time to demonstrate working with `linetype`
# Use `get_help("tribble")` to learn about making your own tibbles directly in R.
tibble::tribble(
  ~year, ~value, ~data_group,
  2000, 5, "A",
  2000, 7, "B",
  2000, 8, "C",
  2001, 7, "A",
  2001, 12, "B",
  2001, 11, "C",
  2002, 9, "A",
  2002, 14, "B",
  2002, 16, "C"
) -> time_demo_tibble

# Show tibble:
time_demo_tibble
## # A tibble: 9 × 3
##    year value data_group
##   <dbl> <dbl> <chr>     
## 1  2000     5 A         
## 2  2000     7 B         
## 3  2000     8 C         
## 4  2001     7 A         
## 5  2001    12 B         
## 6  2001    11 C         
## 7  2002     9 A         
## 8  2002    14 B         
## 9  2002    16 C
# Plot value over time, with one line per group, using `scale_linetype_manual()` to customize lines
# See `get_help("geom_line")` for more information about types of line types
ggplot(time_demo_tibble) + 
  aes(x = year, 
      y = value,
      group = data_group, # needed for grouped line plots
      linetype = data_group) + 
  geom_line() +
  scale_linetype_manual(
    values = c(3,1,2)
  )