I would like to label my geom_smooth
in r but the labels are closer to the actual points, and not to the lines.
Data:
df <- structure(list(t = c(45, 45, 45, 45, 45, 46, 46, 46, 46, 46,
47, 47, 47, 47, 47, 48, 48, 48, 48, 48, 49, 49, 49, 49, 49, 50,
50, 50, 50, 50, 51, 51, 51, 51, 51, 52, 52, 52, 52, 52, 53, 53,
53, 53, 53, 54, 54, 54, 54, 54, 55, 55, 55, 55, 55, 56, 56, 56,
56, 56, 57, 57, 57, 57, 57, 58, 58, 58, 58, 58, 59, 59, 59, 59,
59, 60, 60, 60, 60, 60, 61, 61, 61, 61, 61, 62, 62, 62, 62, 62,
63, 63, 63, 63, 63, 64, 64, 64, 64, 64, 65, 65, 65, 65, 65),
x = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1), name = c("P1", "P2",
"P2 ", "P3", "P4", "P1", "P2", "P2 ", "P3", "P4", "P1", "P2",
"P2 ", "P3", "P4", "P1", "P2", "P2 ", "P3", "P4", "P1", "P2",
"P2 ", "P3", "P4", "P1", "P2", "P2 ", "P3", "P4", "P1", "P2",
"P2 ", "P3", "P4", "P1", "P2", "P2 ", "P3", "P4", "P1", "P2",
"P2 ", "P3", "P4", "P1", "P2", "P2 ", "P3", "P4", "P1", "P2",
"P2 ", "P3", "P4", "P1", "P2", "P2 ", "P3", "P4", "P1", "P2",
"P2 ", "P3", "P4", "P1", "P2", "P2 ", "P3", "P4", "P1", "P2",
"P2 ", "P3", "P4", "P1", "P2", "P2 ", "P3", "P4", "P1", "P2",
"P2 ", "P3", "P4", "P1", "P2", "P2 ", "P3", "P4", "P1", "P2",
"P2 ", "P3", "P4", "P1", "P2", "P2 ", "P3", "P4", "P1", "P2",
"P2 ", "P3", "P4"), value = c(48L, 132L, 111L, 115L, 2L,
58L, 126L, 82L, 74L, 0L, 45L, 119L, 78L, 87L, 0L, 56L, 106L,
105L, 88L, 1L, 52L, 78L, 91L, 107L, 1L, 35L, 96L, 86L, 98L,
1L, 61L, 118L, 90L, 108L, 2L, 45L, 114L, 93L, 98L, 2L, 55L,
108L, 78L, 76L, 7L, 44L, 97L, 94L, 96L, 0L, 40L, 111L, 93L,
88L, 1L, 43L, 78L, 66L, 113L, 2L, 20L, 57L, 84L, 41L, 0L,
17L, 51L, 81L, 34L, 0L, 40L, 55L, 64L, 32L, 0L, 25L, 67L,
71L, 37L, 0L, 16L, 67L, 60L, 57L, 0L, 23L, 46L, 62L, 47L,
1L, 34L, 75L, 68L, 39L, 0L, 34L, 60L, 85L, 24L, 0L, 20L,
58L, 63L, 37L, 1L)), row.names = c(NA, -105L), class = c("tbl_df",
"tbl", "data.frame"))
My code:
df %>%
group_by(name) %>%
# New column to label the first and last values
mutate(label =
case_when(
t == min(t) | t == max(t) ~ name,
TRUE ~ NA_character_)) %>%
ggplot(aes(x = t, y = value, color = name, group = interaction(x, name), shape = name))
geom_smooth(se = F)
geom_vline(xintercept = 57, linetype = "dashed", lwd = 0.3)
scale_color_discrete(guide = 'none')
geom_label_repel(aes(label = label))
Also, is it possible to get rid of the lines pointing to the smoothed loess curves?
CodePudding user response:
One option to achieve your desired result would be to use stat="smooth"
in ggrepel::geom_label_repel
. Doing so will put the labels on the fitted points instead of on the data points. However, to make this work you have to add the labels on the fly inside geom_label_repel
using e.g.
after_stat(ifelse(x %in% range(x), color, NA_character_))
:
library(ggplot2)
library(ggrepel)
ggplot(df, aes(x = t, y = value, color = name, group = interaction(x, name), shape = name))
geom_smooth(se = F)
geom_vline(xintercept = 57, linetype = "dashed", lwd = 0.3)
scale_color_discrete(guide = "none")
ggrepel::geom_label_repel(aes(label = after_stat(ifelse(x %in% range(x), color, NA_character_))), stat = "smooth")
#> `geom_smooth()` using method = 'loess' and formula 'y ~ x'
#> `geom_smooth()` using method = 'loess' and formula 'y ~ x'
#> Warning: Removed 790 rows containing missing values (geom_label_repel).