Skip to content
R for the Rest of Us: A Statistics-Free Introduction is out now! Check it out →
R for the Rest of Us Logo

Adding Text to Plots

This lesson is locked

Get access to all lessons in this course.

If the video is not playing correctly, you can watch it in a new window

Transcript

Click on the transcript to go to that point in the video. Please note that transcripts are auto generated and may contain minor inaccuracies.

View code shown in video
# Load Packages -----------------------------------------------------------

library(tidyverse)

# Import Data -------------------------------------------------------------

penguins <- read_csv("penguins.csv")

# Adding Text to Plots ---------------------------------------------------------

# Text is just another geom. 
# We can use geom_text() to add labels to our figures.

ggplot(data = penguin_bill_length_by_island,
       mapping = aes(x = island,
                     y = mean_bill_length,
                     fill = island,
                     label = mean_bill_length)) +
  geom_col() +
  geom_text()

# Those text labels are too long!
# Let's create a new variable to use for plotting.
# We're using the number() function from the scales package 
# to make this variable

library(scales)

penguin_bill_length_by_island_v2 <- penguin_bill_length_by_island |> 
  mutate(mean_bill_length_one_digit = number(mean_bill_length, accuracy = 0.1))

# Now let's plot using our new data frame

ggplot(data = penguin_bill_length_by_island_v2,
       mapping = aes(x = island,
                     y = mean_bill_length,
                     fill = island,
                     label = mean_bill_length_one_digit)) +
  geom_col() +
  geom_text()

# Note that we use mean_bill_length_one_digit for the label aesthetic property
# and mean_bill_length for y. 
# If you use mean_bill_length_one_digit for both, your graph will
# look different.

ggplot(data = penguin_bill_length_by_island_v2,
       mapping = aes(x = island,
                     y = mean_bill_length_one_digit,
                     fill = island,
                     label = mean_bill_length_one_digit)) +
  geom_col() +
  geom_text()

# We can use the hjust and vjust arguments to horizontally and vertically 
# adjust text.

# vjust = 0 puts the labels on the outer edge of the bars.

ggplot(data = penguin_bill_length_by_island_v2,
       mapping = aes(x = island,
                     y = mean_bill_length,
                     fill = island,
                     label = mean_bill_length_one_digit)) +
  geom_col() +
  geom_text(vjust = 0)

# vjust = 1 puts the labels at the inner edge of the bars.

ggplot(data = penguin_bill_length_by_island_v2,
       mapping = aes(x = island,
                     y = mean_bill_length,
                     fill = island,
                     label = mean_bill_length_one_digit)) +
  geom_col() +
  geom_text(vjust = 1)

# I often do something like vjust = 1.5 to give a bit more padding. 

ggplot(data = penguin_bill_length_by_island_v2,
       mapping = aes(x = island,
                     y = mean_bill_length,
                     fill = island,
                     label = mean_bill_length_one_digit)) +
  geom_col() +
  geom_text(vjust = 1.5)

# We can adjust the color of the text using the color argument. 
# We're putting it outside of the aes() because we are setting it 
# for the whole layer.

ggplot(data = penguin_bill_length_by_island_v2,
       mapping = aes(x = island,
                     y = mean_bill_length,
                     fill = island,
                     label = mean_bill_length_one_digit)) +
  geom_col() +
  geom_text(vjust = 1.5,
            color = "white")

# geom_label() is nearly identical but it adds a background. 
# With geom_label() the color argument determines the text and border color 
# while the fill is the background color.

ggplot(data = penguin_bill_length_by_island_v2,
       mapping = aes(x = island,
                     y = mean_bill_length,
                     fill = island,
                     label = mean_bill_length_one_digit)) +
  geom_col() +
  geom_label(vjust = 1.5,
             color = "white",
             fill = "black")

Your Turn

# Load Packages -----------------------------------------------------------

library(tidyverse)

# Import Data -------------------------------------------------------------

penguins <- read_csv("penguins.csv")
			
# Adding Text to Plots ---------------------------------------------------------

# Copy your last code chunk. 
# Then add text labels on the top of each bar that show the number of penguins of each species.
# You'll need to use geom_text() and the vjust argument to do this.
# Make the text labels show up in red.

# YOUR CODE HERE

# Do the same thing, but use geom_label() instead of geom_text().
# This time, make the text itself show up in white.

# YOUR CODE HERE

Learn More

Data Visualization: A Practical Introduction has a section in Chapter 5 on adding text to plots, as does Chapter 11 of R for Data Science.

Information about using vjust and hjust is on the geom_label page of the tidyverse website.

Also, check out the ggrepel package , which automatically adjusts overlapping text and labels.

Have any questions? Put them below and we will help you out!

You need to be signed-in to comment on this post. Login.

Ashley Robinson

Ashley Robinson

March 28, 2024

When I added this text, my legend also got a little "a" in each color box that matched the label. Can you explain why and how to remove?

Libby Heeren

Libby Heeren Coach

March 28, 2024

Hi, Ashley! I'm sure you were with us when we talked about it in live session, but I wanted to answer here, too! To get rid of it, the method I use is to add an argument inside my geom_text() function that removes our text geom from being included in the legend. It looks like this:

geom_text(show.legend = FALSE)

As for why it's popping up in your particular code and not in David's here, it might depend on what exactly you've got in your code! Feel free to share it and we can figure it out 🤔

Kristen Rudd

Kristen Rudd

April 18, 2024

Pending approval

Hi, I wanted to do some extra practice beyond the "try this"section and tried the mutate function to shorten the text labels. however, I got an error that said "could not find the "mutate" function. Am I missing something?

install.packages("scales")

library(scales)

pengiun_bill_length_by_island_v2 <- pengiun_bill_length_by_island |> mutate(mean_bill_length_one_digit = number(mean_bill_length, accuracy = 0.1))