rggplot2abline

restrict range of geom_abline(slope=somenumber)


I am trying to restrict the ranges of geom_abline. In the plot below, I would like the red line to stop at the xvalue 5 and the blue line to start at the value 5 (in the picture, I marked by hand the segments that need to be removed).

obs: I understand that aes and slope can not be used together, but still put it in the code, as a form of pseudocode, to clarify what I wanted ggplot2 to let me do.

library(tidyverse)
d <- data.frame(x=1:10,y=2:11)
d %>% ggplot(aes(x,y)) + geom_point() +
  geom_abline(aes(xmax=5),slope = 1,color='red') +
  geom_abline(aes(xmin=5),slope = 1,intercept = 3,color='blue')

enter image description here

The R outputs the warning:

Warning messages:
1: geom_abline(): Ignoring `mapping` because `slope` and/or `intercept` were provided. 
2: geom_abline(): Ignoring `mapping` because `slope` and/or `intercept` were provided.

Solution

  • You can do this using geom_function() in place of geom_abline(), and specify a Vectorized function. If you're uncertain what is meant by "Vectorizing" a function, the idea is that we want the function to return NA if the x value is in a range where we don't want the line to appear, but otherwise return the line. In order to have your function be evaluated along each x value like this, you need to have the function evaluate one-by-one (vectorized). If you don't vectorize the function, you can't use if statements in there.

    d %>% ggplot(aes(x,y)) + geom_point() +
      # geom_abline(aes(xmax=5),slope = 1,color='red') +
      geom_function(fun=Vectorize(function(x) {
        if(x > 5)
          return(NA)
        else
          return(x)
        }), color='red') +
      
      # geom_abline(aes(xmin=5),slope = 1,intercept = 3,color='blue') +
      geom_function(fun=Vectorize(function(x) {
        if(x > 5)
          return(x+3)
        else
          return(NA)
        }), color='blue')
    

    enter image description here