Home > Back-end >  ggrepel together with geom_smooth
ggrepel together with geom_smooth

Time:07-05

ggplot(gapminder::gapminder,aes(x=year,y=lifeExp,label=continent,color=continent)) 
geom_line(size=.1,alpha=.2) 
guides(color="none") 
theme_minimal() 
geom_smooth(aes(color=continent),se=F,method="loess") 
ggrepel::geom_label_repel(direction = "y",stat="smooth",nudge_x = 5)

Results in the following: enter image description here

I only want one label for each smoothed aggregate for each continent.

I´ve tried tweaking the parameters, but to no help. If I skip the stat="smooth" term from geom_label_repel It goes all haywire and tries to label all the individual lines - not the smoothed lines. Any ideas?

CodePudding user response:

One way you could do this is to get the last (or first etc. as desired) fitted value for each continent in a summary label data frame, then use that in ggrepel:

library(tidyverse)
library(gapminder)
library(ggrepel)
library(broom)

label_df <- gapminder |> 
  nest(data = -continent) |> 
  mutate(model = map(data, ~loess(lifeExp ~ year, .x)),
         augmented = map(model, augment),
         fitted = map(augmented, ".fitted") |> map_dbl(last),
         year = map(data, "year") |> map_int(last)) |> 
  select(continent, fitted, year)

ggplot(gapminder, aes(year, lifeExp, color = continent))  
  geom_line(size = .1, alpha = .2)  
  guides(color = "none")  
  theme_minimal()  
  geom_smooth(aes(color = continent), se = F, method = "loess")  
  geom_label_repel(aes(year, fitted, label = continent), data = label_df)

Created on 2022-07-03 by the reprex package (v2.0.1)

  • Related