Home > Software engineering >  How to draw a horizontal line and a vertical line that cross at the intersection with the line of a
How to draw a horizontal line and a vertical line that cross at the intersection with the line of a

Time:12-20

I made a plot with points connected with a line. In this plot I want to draw a vertical line from a point on the x-axis to the intersection with the plot line.And at the intersection, I want to draw a horizontal line to the Y-axis. I have searched several websites, forums and tutorials, but I still can't do it. Any help?

library(ggplot2)

X <- 1:5
Y <- c(2, 6, 4, 7, 12)

DF <- data.frame(X, Y)

ggplot(data = DF,
       aes(x = X,
           y = Y))  
  geom_point()  
  geom_line()  
  geom_vline(xintercept = 4.5,
             linetype = 2)

Result so far:

enter image description here

Example of desired result:

enter image description here enter image description here

CodePudding user response:

Already commented by @Eric but also sort of answered by @akrun in enter image description here

CodePudding user response:

As already mentioned by @Eric in his comment geom_segment is the way to go to achieve your desired result. Moreover, you have to manually compute the y value where the segments should cut the geom_line which could be achieved using approx. As quick approach may look like so:

library(ggplot2)

X <- 1:5
Y <- c(2, 6, 4, 7, 12)

DF <- data.frame(X, Y)

# vertical line
vsegment <- function(x, X, Y) {
  geom_segment(aes(x = x, xend = x, y = -Inf, yend = approx(X, Y, x)$y),
               linetype = 2)  
}
# horizontal line
hsegment <- function(x, X, Y) {
  geom_segment(aes(x = -Inf, xend = x, y = approx(X, Y, x)$y, yend = approx(X, Y, x)$y),
               linetype = 2)  
}
ggplot(data = DF,
       aes(x = X,
           y = Y))  
  geom_point()  
  geom_line()  
  vsegment(4.5, X, Y)  
  hsegment(4.5, X, Y)

CodePudding user response:

You can use geom_path() as well for this

X <- 1:5
Y <- c(2, 6, 4, 7, 12)

DF <- data.frame(X, Y)
          
ggplot(data = DF, aes(x = X, y = Y))  
  geom_point()  
  geom_line()  
  geom_path(data = data.frame(x = c(-Inf, 4.5, 4.5), y = c(approx(X, Y, 4.5)$y, approx(X, Y, 4.5)$y, -Inf)), aes(x, y), color = "red", linetype = 2)

enter image description here

If you want it more flexible for more intercepts you can use this function. Note the ... part, so you can pass the geom_path arguments along, like color, linetype, size, etc. It supports an intercept based on the x value or based on the y value.

my_intercept <- function(x, y, ...) {
  if (!missing(x)) dt <- data.frame(x = c(-Inf, x, x), y = c(approx(X, Y, x)$y, approx(X, Y, x)$y, -Inf))
  if (!missing(y)) dt <- data.frame(x = c(-Inf, approx(Y, X, y)$y, approx(Y, X, y)$y), y = c(y, y, -Inf))
  geom_path(data = dt, aes(x, y), ...)
}

ggplot(data = DF, aes(x = X, y = Y))  
  geom_point()  
  geom_line()  
  my_intercept(x = 4.5, color = "blue", linetype = 2)  
  my_intercept(y = 5, color = "red", linetype = 4)

enter image description here

  • Related