I am trying to annotate lines in ggplot
using geom_text_repel
. However, the annotation for some lines is not showing up. How to fix that?
Here is a reproducible example:
library(ggplot2)
library(ggrepel)
df.1 <-
data.frame(
id = rep(c(1, 2, 3),each = 4),
time = c(1, 2, 3, 4),
x = c(1, 2, 3, 4),
y = c(10, 23, 25, 28),
z = c(2, 4, NA, NA)
)
df.long <- df.1 %>% pivot_longer(cols = c(x, y, z), names_to = "class", values_to = "score")
ggplot(df.long, aes(x = time, y = score, col = class, group = class)) +
geom_line() +
geom_point() +
geom_text_repel(
data = subset(df.long, time == max(time)),
aes(label = class),
size = 2,
point.padding = 0.2,
nudge_x = .3,
segment.curvature = -1e-20,
arrow = arrow(length = unit(0.015, "npc"))
)
The annotation for z
is not showing. Also, how can I reduce the annotation to one per line? Right now it has three. Many thanks!
You have to filter the data for the maximum time
with a non-missing value per class
. Also, as there are multiple values (one per id
) per time
and class
you get multiple labels. Hence, if you only one label get rid of the duplicates using e.g. dplyr::distinct
:
library(dplyr, warn=FALSE)
library(ggplot2)
library(ggrepel)
df_labels <- df.long |>
drop_na() |>
filter(time == max(time), .by = class) |>
distinct(time, class, score)
ggplot(df.long, aes(x = time, y = score, col = class, group = class)) +
geom_line() +
geom_point() +
geom_text_repel(
data = df_labels,
aes(label = class),
size = 2,
point.padding = 0.2,
nudge_x = .3,
arrow = arrow(length = unit(0.015, "npc"))
)
#> Warning: Removed 6 rows containing missing values (`geom_line()`).
#> Warning: Removed 6 rows containing missing values (`geom_point()`).