Home > Software design >  How to accurately add a intersection line on a plot in R?
How to accurately add a intersection line on a plot in R?

Time:02-22

I am trying to add a right angled intersection line to a ggplot.

For example, in the code\plot below, I draw a dashed line at some given threshold x-value. Ideally, I want this line to intersect the the curve and go to the corresponding spot on the y-axis. As you can see, at the moment I just extend it to y=1.

I was wondering if there was a way to find the corresponding y-value, if given only the x-value for any type of curve?

library(ggplot2)

# create data
df <- data.frame(
  x = seq(0,1, by = 0.1),
  y =  pexp(seq(0, 1, by = 0.1), rate = 4)
)

# set treshold
threshold <- 0.5

# plot
ggplot(df, aes(x, y))  
  geom_line()  
  geom_segment(aes(x = threshold, xend = threshold, y = -Inf,  yend = 1), linetype = 2) 
  geom_segment(aes(x = -Inf, xend = threshold, y = 1, yend = 1),  linetype = 2)  
  theme_bw()

plot with intersection line

CodePudding user response:

Do you mean this?

df2 <- with(approx(df$x, df$y, xout = threshold),
            data.frame(x1 = c(-Inf, x, x), y1 = c(y, y, -Inf)))
ggplot(df, aes(x, y))  
  geom_line()  
  geom_line(aes(x = x1, y = y1), linetype = 2, data = df2)  
  theme_bw()

exponential curve with intersecting lines

CodePudding user response:

You could predict a loess regression to find the desired y value.

(y1 <- predict(loess(y ~ x, df), newdata=list(x=threshold)))
#         x 
# 0.8657561     

plot(y ~ x, df, type='l', col=4, xaxs='i', yaxs='i')
segments(0, y1, threshold, y1, lty=3, col=2)
segments(threshold, y1, threshold, 0, lty=3, col=2)
## optional:
mtext(round(y1, 2), 2, at=y1, col=2)
mtext(threshold, 1, at=threshold, col=2)

enter image description here

When you have a "real" curve, i.e. the function is known:

set.seed(42)
cf <- runif(5)
f <- \(x) cf[1]   cf[2]*x   cf[3]*x^2   cf[4]*x^3   cf[5]*x^4
y2 <- f(threshold)

curve(f)
segments(par()$usr[1], y2, threshold, y2, lty=2, col=2)  ## `par` gives margins
segments(threshold, y2, threshold, 0, lty=2, col=2)

enter image description here

Using the ggplot2 package

library(ggplot2)
ggplot(df, aes(x, y))  
  geom_line()  
  geom_segment(aes(x=threshold, xend=threshold, y=-Inf,  yend=y1), linetype=2)  
  geom_segment(aes(x=-Inf, xend=threshold, y=y1, yend=y1),  linetype=2)  
  theme_bw()

enter image description here

  •  Tags:  
  • r
  • Related