rggplot2direct-labels

Direct labels puts labels at wrong place


I'm trying to do a plot with ggplot2 and trying to put labels at the right place on mean trajectories with confidence regions. Since I cannot share my data, I created a reproducible example:

set.seed(456)
library(ggplot2)
library(directlabels)
time<-1:25
df2<-data.frame(time,value=runif(2500),group=as.factor(c(rep('Alpha',1250),rep('Beta',1250))))
ggplot(df2, aes(x=time, y=value,group=group,colour=group))+
      stat_summary(geom="ribbon", fun.data=mean_cl_normal,fun.args=list(conf.int=0.95), fill="grey")+
      stat_summary(geom="line", fun=mean,size=2,show.legend=TRUE)+
      stat_summary(geom="point", fun=mean, color="red",size=3)+
      theme(legend.position='none',axis.title=element_text(size=40),
        axis.text=element_text(size=30),panel.background = element_blank(),axis.line = 
        element_line(colour = 'black'))+
      geom_dl(aes(label = group),method=list(dl.combine('first.qp','last.qp')),color='black')

I obtain the following plot: enter image description here

As you can see, the labels are completely wrong. I'm trying to put the labels next to the first mean point and/or next to the last mean point. With my data, the result is worse: both labels are under the lower trajectory and both overlapped. I also get the following warning:

┌ Warning: RCall.jl: Warning in regularize.values(x, y, ties, missing(ties)) :
│   collapsing to unique 'x' values
│ Warning in regularize.values(x, y, ties, missing(ties)) :
│   collapsing to unique 'x' values
│ Warning in regularize.values(x, y, ties, missing(ties)) :
│   collapsing to unique 'x' values
│ Warning in regularize.values(x, y, ties, missing(ties)) :
│   collapsing to unique 'x' values

How can I solve my problem and put the labels next to the first/last mean values of each trajectory? I tried to change the method option but with no success... As the plotted points are means, the methods with .points don't work. Moreover, how can I control the size of labels?

I tried another ggplot2code:

ggplot(df2, aes(x=time, y=value,group=group,colour=group))+
       stat_summary(geom="ribbon", fun.data=mean_cl_normal,
                fun.args=list(conf.int=0.95), fill="grey")+
       stat_summary(geom="line", fun=mean,size=2,show.legend=TRUE)+
       stat_summary(geom="point", fun=mean, color="red",size=3)+
       theme(legend.position = 'none',axis.title=element_text(size=40),
                axis.text=element_text(size=30),panel.background = 
                element_blank(),axis.line = element_line(colour = 
                'black'))+
       stat_summary(aes(label=group), fun=mean, geom="text", size=8)

and I obtain the following plot:

enter image description here

I think I'm close with this last plot, if I can keep only the first and/or last labels.


Solution

  • You were already on the right track with your last approach. To make it work you have to filter your df to include only the obs for the the first and last time. Try this:

    set.seed(456)
    library(ggplot2)
    library(dplyr)
    
    time<-1:25
    df2<-data.frame(time,value=runif(2500),group=as.factor(c(rep('Alpha',1250),rep('Beta',1250))))
    
    dlabs <- df2 %>%
      group_by(group) %>% 
      arrange(time) %>% 
      filter(time %in% c(first(time), last(time)))
    
    ggplot(df2, aes(x=time, y=value,group=group,colour=group))+
      stat_summary(geom="ribbon", fun.data=mean_cl_normal,fun.args=list(conf.int=0.95), fill="grey")+
      stat_summary(geom="line", fun=mean,size=2,show.legend=TRUE)+
      stat_summary(geom="point", fun=mean, color="red",size=3)+
      theme(legend.position='none',axis.title=element_text(size=40),
            axis.text=element_text(size=30),panel.background = element_blank(),axis.line = 
              element_line(colour = 'black'))+
      stat_summary(data = dlabs, aes(label = group, hjust = ifelse(time == first(time), 1.2, -.2)), fun = mean, geom = "text", color = "black") +
      scale_x_continuous(expand = expansion(mult = .1))