0

I would like to add a point (lollipop alike) at the end of a smooth line in ggplot2.

This is the current graph: enter image description here

and this is the graph I would like to get (image modified in an image editor to show): enter image description here

Example of code:

df.test <- structure(list(Country = c("USA", "USA", "USA", "USA", "USA", 
"USA", "USA", "USA", "USA", "USA", "USA", "USA", "USA", "USA", 
"USA", "USA", "USA", "USA", "USA", "USA", "USA"), startDate = structure(c(18622, 
18623, 18624, 18625, 18626, 18627, 18628, 18629, 18630, 18631, 
18632, 18633, 18634, 18635, 18636, 18637, 18638, 18639, 18640, 
18641, 18642), class = "Date"), endDate = structure(c(20332, 
20878, 20819, 20666, 20485, 20332, 20209, 20089, 20028, 19997, 
20028, 19967, 19875, 19754, 19662, 19509, 19389, 19358, 19297, 
19266, 19236), class = "Date")), row.names = c(NA, -21L), class = c("tbl_df", 
"tbl", "data.frame"))

ggplot(df.test, aes(x=startDate, y=endDate)) +
  geom_line(color='lightgrey') +
  geom_smooth(method="auto", se=FALSE, fullrange=FALSE, size = 0.75) +
  theme_light() +
  ggtitle('title') +
  xlab('Start date') +
  ylab('Expected end date')

Thank you.

Sal
  • 117
  • 12
  • Provide an example dataset in `dput()` format and code you have tried. Please visit [How to make a great R reproducible example](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) – UseR10085 Jan 16 '21 at 04:56

1 Answers1

2

According to this post (https://stackoverflow.com/a/9790803), you may first obtain the data of smooth line as fit object by the following code:

ggplot(df.test, aes(x=startDate, y=endDate)) +
  geom_smooth(aes(outfit=fit<<-..y..), method="auto")

and use that fit object to draw the point:

ggplot(df.test, aes(x=startDate, y=endDate)) +
  geom_line(color='lightgrey') +
  geom_smooth(method="auto", se=FALSE, fullrange=FALSE, size = 0.75) +
  geom_point(data=tibble(startDate=df.test %>% filter(row_number()==n()) %>% .$startDate,
                         endDate=structure(fit[length(fit)], class="Date")), colour="purple") +
  theme_light() +
  ggtitle('title') +
  xlab('Start date') +
  ylab('Expected end date')
yh6
  • 379
  • 2
  • 13
  • I personally find it not very readable to use such pipe structures as a data argument in geoms, but I guess that's a style question. (you will find your code easier to debug though when you keep those things separate... ) +1 – tjebo Jan 16 '21 at 22:24
  • as a side, may I remind of Burns' _[R Inferno](https://www.burns-stat.com/pages/Tutor/R_inferno.pdf)_ circle 6 - in which you find the wonderful phrase: _"... What’s so wrong about global assignments? Surprise. Surprise in movies and novels is good. Surprise in computer code is bad."_ – tjebo Jan 16 '21 at 22:30
  • Thanks for your kind comments. You're totally right. I will keep them in mind. – yh6 Jan 17 '21 at 02:03
  • 1
    Although the code becomes a bit lengthy, it would be better to directly estimate the predicted values using `loess` or `gam` instead of using global assignment. – yh6 Jan 17 '21 at 02:06