简体   繁体   中英

Annotate a geom_smooth line in ggplot

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:

在此处输入图像描述

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.

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)

在此处输入图像描述

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM