rggplot2ggrepelgeom

Geom_label_repel not properly referencing to the sec.axis


I am working with a ggplot that has two axis: one for the geom_bar component, and the other for the geom_linecomponent. And for this, I am using the sec.axis() command.

I wanted to insert a box to provide the last value of the geom_line component, but I am struggling because I believe that while using the commmand geom_label_repel, the aesthetic being used, is referent to the geom_barcomponent.

I'll provide a similar data to illustrate what I am saying.

df <- data.frame(day = as.character(seq(from = 1, to = 100, by = 1)),
             total = rbinom(n=100,30,0.5), 
             prop = runif(100))

df <- df %>% arrange(df, by = day)
df$`percentage` <- label_percent(accuracy = 0.01)(df$prop)


ggplot(data = df, 
       aes(x = day, y = total)) +
  geom_bar(stat = "identity", fill = "lightgreen", width = 0.35) + 
  geom_line(data = df, 
            aes(x = day, y = (prop)*15, group = 1), 
            color = "red", size = 1,inherit.aes = TRUE) +
  scale_y_continuous( 
    labels = function(x) format(x, scientific = FALSE),
    #breaks = seq(from = 0, to = 10000000,by = 100000),
    sec.axis = sec_axis(trans = ~./15, 
                        name = "Secondary axis",
                        breaks = seq(from = 0, to = 10, by = 0.1),
                        scales::percent))+
  theme(axis.text.x = element_text(angle = 90, vjust = 0.5))+
  geom_label_repel(data=df[nrow(df),], 
                   aes(x = day, 
                       y = prop*1,
                       label = round(prop*100,2)),
                   color = 'red',
                   segment.alpha = 0.5) +
  scale_x_discrete(expand = expansion(add = c(0, 7)))

Which outputs the following image:

example

As you can tell, it works well in regards to obtaining the last number of the prop column, which is intended, but it is not automatically placed beside the geom_line. I have tried messing with the nudge_xand nudge_y commands but it didn't lead me to anywhere, given the fact that I want to have this "number placement" automatic.

Can anyone help?


Solution

  • The sec.axis is in some ways just decorative. ggplot is plotting everything by the main axis. To make the label follow the line, make the same transform as in your geom_line call (y = prop*15):

    library(tidyverse)
    library(ggrepel)
    df <- data.frame(day = as.character(seq(from = 1, to = 100, by = 1)),
                     total = rbinom(n=100,30,0.5), 
                     prop = runif(100))
    
    df <- df %>% arrange(df, by = day)
    df$`percentage` <- scales::label_percent(accuracy = 0.01)(df$prop)
    
    
    ggplot(data = df, 
           aes(x = day, y = total)) +
      geom_bar(stat = "identity", fill = "lightgreen", width = 0.35) + 
      geom_line(data = df, 
                aes(x = day, y = (prop)*15, group = 1), 
                color = "red", size = 1,inherit.aes = TRUE) +
      scale_y_continuous( 
        labels = function(x) format(x, scientific = FALSE),
        #breaks = seq(from = 0, to = 10000000,by = 100000),
        sec.axis = sec_axis(trans = ~./15, 
                            name = "Secondary axis",
                            breaks = seq(from = 0, to = 10, by = 0.1),
                            scales::percent))+
      theme(axis.text.x = element_text(angle = 90, vjust = 0.5))+
      geom_label_repel(data=df[nrow(df),], 
                       aes(x = day, 
                           y = prop*15,
                           label = round(prop*100,2)),
                       color = 'red',
                       segment.alpha = 0.5) +
      scale_x_discrete(expand = expansion(add = c(0, 7)))
    #> Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
    #> ℹ Please use `linewidth` instead.