Home > Mobile >  Annotate a geom_smooth line in ggplot
Annotate a geom_smooth line in ggplot

Time:06-02

Given the following dummy dataset

df = structure(list(date = structure(c(19128, 19129, 19130, 19131, 
                                   19132, 19133, 19134, 19135, 19136, 19137, 19138, 19139, 19140, 
                                   19141, 19142, 19143, 19144), class = "Date"), av7 = c(108.55, 
                                                                                         108.875, 108.916666666667, 108.725, 108.92, 108.877777777778, 
                                                                                         108.841666666667, 108.70119047619, 108.525, 108.329761904762, 
                                                                                         108.115476190476, 107.94880952381, 107.877380952381, 107.652380952381, 
                                                                                         107.609523809524, 107.495238095238, 107.390476190476), ch7 = c(-0.15, 
                                                                                                                                                        -0.35, -0.59, -0.61, -0.97, -1, 0, 0.15, -0.35, -0.59, -0.61, -0.97, -1, 
                                                                                                                                                        -1.19, -1.09, -1.03, -0.94)), row.names = c(NA, -17L), class = c("tbl_df", 
                                                                                                                                                                                                                         "tbl", "data.frame"))

I would like to make a smooth line for the av7 variable and annotate that line with values from the ch7 variable. I tried this code:

ggplot(df, aes(x = date, y=av7, label = ch7)) 
  geom_smooth(se=F) 
  geom_text(nudge_y = 0.2)

However, As you can see below, the position of the label does not align with the of the smoothed line as it follows the position of the original points:

enter image description here

I also tried to use stat = "smooth" witin geom_text as follows:

ggplot(df, aes(x = date, y=av7, label = ch7)) 
  geom_smooth(se=F) 
  geom_text(nudge_y = 0.2,
            stat = "smooth")

But I got the following error:

Error: geom_text requires the following missing aesthetics: label

Any help would be much appreciated.

CodePudding user response:

One approach is to assign the values of the loess smooth to the original data frame, and then plot the line and the points separately:

df <- df %>% mutate(sm = predict(loess(av7~as.numeric(date), data=df)))

ggplot(df, aes(x = date, y=sm, label = ch7)) 
  geom_line(color="blue")   geom_text(nudge_y=0.2)

enter image description here

CodePudding user response:

If x positioning is not exactly important, then you could also make use of the geomtextpath package. Sadly, it currently only allows one label per line, therefore you'll be limited to collapsing your labels and kind of faking its spread over the line. This only works if you want to more or less equally spread it over the curve.

library(geomtextpath)
#> Loading required package: ggplot2
df = structure(list(date = structure(c(19128, 19129, 19130, 19131, 
                                       19132, 19133, 19134, 19135, 19136, 19137, 19138, 19139, 19140, 
                                       19141, 19142, 19143, 19144), class = "Date"), av7 = c(108.55, 
                                                                                             108.875, 108.916666666667, 108.725, 108.92, 108.877777777778, 
                                                                                             108.841666666667, 108.70119047619, 108.525, 108.329761904762, 
                                                                                             108.115476190476, 107.94880952381, 107.877380952381, 107.652380952381, 
                                                                                             107.609523809524, 107.495238095238, 107.390476190476), ch7 = c(-0.15, 
                                                                                                                                                            -0.35, -0.59, -0.61, -0.97, -1, 0, 0.15, -0.35, -0.59, -0.61, -0.97, -1, 
                                                                                                                                                            -1.19, -1.09, -1.03, -0.94)), row.names = c(NA, -17L), class = c("tbl_df", 
                                                                                                                                                                                                                             "tbl", "data.frame"))
ggplot(df, aes(x = date, y = av7))  
  geom_textsmooth(aes(label = paste(ch7, collapse = "  ")))
#> `geom_smooth()` using method = 'loess' and formula 'y ~ x'

Created on 2022-06-01 by the reprex package (v2.0.1)

  • Related