Home > Software engineering >  Labelling function for y-axis ggplot (How to hide labels for negative breaks)
Labelling function for y-axis ggplot (How to hide labels for negative breaks)

Time:02-17

I have this data:

structure(list(date = structure(c(18474, 18832, 18861, 18666, 
18597, 18517, 18938, 18611, 18384, 18768, 18633, 18545, 18550, 
18577, 18354, 18584, 18821, 18338, 18815, 18591, 18799, 18721, 
18945, 18448, 18445, 18765, 18784, 18683, 19012, 18505, 18991, 
18346, 18899, 18470, 18514, 18774, 18943, 18834, 18424, 18506, 
18844, 18988, 18418, 18951, 18678, 18454, 18552, 19021, 18414, 
18958), class = "Date"), value = c(10, 28, 87, 105, 345, 40, 
592, 220, 5, 51, 160, 78, 91, 529, 51, 552, 13, 13, 7, 435, 11, 
250, 848, 7, 5, 60, 25, 145, 1493, 22, 186, 44, 138, 9, 29, 40, 
779, 29, 2, 22, 38, 164, 2, 1058, 126, 7, 98, 2502, 2, 1010)), row.names = c(NA, 
-50L), class = c("tbl_df", "tbl", "data.frame"))

A simple

ggplot(df, aes(date, value))   geom_col()

gives this:

enter image description here

However, I'd like to have breaks from -2000 to 2000 at every 1000. For the negative values I want to draw the horizontal grid lines, however I do not want to label these breaks at the y-axis. So I do the following:

ggplot(df, aes(date, value))    
  geom_col()  
  scale_y_continuous(
    limits = c(-3000,3000),
    breaks = c(-2000, -1000, 0,1000,2000),
    labels = function(x){
      if(x < 0){
        return("")
      }else{
        return(x)
      }
    }
  )

But this does not work saying: Error: Breaks and labels are different lengths Run rlang::last_error() to see where the error occurred. In addition: Warning message: In if (x < 0) { : the condition has length > 1 and only the first element will be used

I thought it would somehow check each break and I could return the label from this function.

I can do this:


ggplot(df, aes(date, value))    
  geom_col()  
  scale_y_continuous(
    limits = c(-3000,3000),
    breaks = c(-2000, -1000, 0,1000,2000),
    labels = c("", "", 0, 1000, 2000)
  )

Which gives the desired output:

enter image description here

But I do not think this is the best option.

CodePudding user response:

It's because if isn't vectorized, look at the warning message when running your breaking code above:

Warning message: In if (x < 0) { : the condition has length > 1 and only the first element will be used

You should use ifelse to return a vector the size of x.

ggplot(df, aes(date, value))    
  geom_col()  
  scale_y_continuous(
    limits = c(-3000,3000),
    breaks = c(-2000, -1000, 0,1000,2000),
    labels = function(x) ifelse(x < 0, "", x)
  )

enter image description here

CodePudding user response:

You can use replace:

ggplot(df, aes(date, value))    
  geom_col()  
  scale_y_continuous(
    limits = c(-3000,3000),
    breaks = seq(-2000, 2000, 1000),
    labels = function(x) replace(x, which(x < 0), "")
  )
  • Related