I am working with ggplot in R Quarto. I am trying to create a line graph with 3 longitudinal variables (so x = Year, Y = Var1, Var2, Var3). I want to show data labels for all three variables for each year. However, the problem is – data labels overlap, so one can’t see all labels. So far, I tried geom_label_repel, but while it tries to separate labels, they still overlap. (As a side note, for some reason, geom_label_repel also puts labels in different positions on a new render). I was wondering if anyone knows a way to automatically make data labels to be separate? (I have many plots like this, so looking for a universal solution rather than for a manual manipulation of this specific plot).
Here the reproducible code I have so far that creates a chart like this:
Chart Example
fontsize: 20pt
echo: FALSE
format:
html:
self-contained: true
knitr::opts_chunk$set(warning = FALSE, message = FALSE)
library(palmerpenguins)
library(readr)
library(tidyverse)
library(ggplot2)
library(ggrepel)
# Creating data
df <- data.frame( Year = c(2020, 2021, 2022, 2023),
Var1 = c(2.01, 3.05, 4.22, 5.29),
Var2 = c(2.20, 3.00, 4.10, 5.02),
Var3 = c(1.98, 2.43, 4.21, 4.85) )
## Identify min and max year
year_1 <- min(df$Year)
year_2 <- max(df$Year)
# Specifying years on the x axis
year_labels <- c("20", "21", "22", "23")
spline_Var1 <- as.data.frame(spline(df$Year, df$Var1))
spline_Var2 <- as.data.frame(spline(df$Year, df$Var2))
spline_Var3 <- as.data.frame(spline(df$Year, df$Var3))
largest <- max(df$Var1, df$Var2, df$Var3)
ggplot(df) +
geom_point(aes(x = Year, y = Var1), size = 3, colour = '#000000') +
geom_line(data = spline_Var1, aes(x = x, y = y, colour = "Variable 1"), size = 1) +
geom_point(aes(x = Year, y = Var2), size = 3, colour = '#DC3220') +
geom_line(data = spline_Var2, aes(x = x, y = y, colour = "Variable 2"), size = 1) +
geom_point(aes(x = Year, y = Var3), size = 3, colour = '#005AB5') +
geom_line(data = spline_Var3, aes(x = x, y = y, colour = "Variable 3"), size = 1) +
labs(y = "Variable", x = "Year") + theme(text = element_text(size=14)) +
theme(panel.background = element_blank()) + theme(axis.line = element_line(colour = "#000000")) +
theme(plot.title = element_text(face="bold", size=18)) + theme(plot.title = element_text(hjust = 0.5)) +
theme(plot.subtitle = element_text(hjust = 0.5)) +
theme(panel.grid.major.y = element_line(color = "#D3D3D3", size = 0.5, linetype = 1)) +
theme(panel.grid.minor = element_blank()) + theme(panel.grid.major.x = element_blank()) +
ggtitle("TEST", subtitle = paste0('Years ', year_1, '-', year_2)) +
scale_color_manual(name = "", values = c("Variable 1" = "#000000", "Variable 2" = "#DC3220", "Variable 3" = "#005AB5")) +
scale_x_continuous(breaks=c(year_1:year_2), labels = year_labels, expand = c(0.03,0.03)) +
scale_y_continuous(breaks = round(seq(0, largest, by = 1), 0.01), expand = c(0.03,0.03)) +
theme(legend.position = "bottom") + theme(legend.title=element_blank()) + theme(legend.text=element_text(size=14)) +
theme(axis.title.x = element_text(colour = "#000000", margin = margin(t = 10, r = 0, b = 0, l = 0)),
axis.title.y = element_text(colour = "#000000", margin = margin(t = 0, r = 10, b = 0, l = 0))) +
theme(axis.text.x = element_text(color="#000000"), axis.text.y = element_text(color="#000000")) +
geom_label_repel(aes(x = Year, y = Var1, label = paste0(sprintf("%0.2f", round(Var1, digits = 2)))),
color = "#000000", fontface="bold", label.size = NA) +
geom_label_repel(aes(x = Year, y = Var2, label = paste0(sprintf("%0.2f", round(Var2, digits = 2)))),
color = "#DC3220", fontface="bold", label.size = NA) +
geom_label_repel(aes(x = Year, y = Var3, label = paste0(sprintf("%0.2f", round(Var3, digits = 2)))),
color = "#005AB5", fontface="bold", label.size = NA)
Amanda Lemon is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.