Search code examples
rggplot2datatable

r ggplot: how can I add a maximum distance vertical line of two lines


I have a data table dt like this:

      time   col_A    col_B     diff
1:    930  9925642  10025714  100098.53
2:    931  9925642  10025714  100098.53
3:    932  9925642  10025714  100098.53
4:    933  9925642  10025714  100098.53
5:    934  9925642  10025714  100098.53
---
237: 1456  9949509  10029605  80095.54
238: 1457  9949509  10029605  80095.54
239: 1458  9949509  10029605  80095.54
240: 1459  9949509  10029605  80095.54
241: 1500  9949509  10029605  80095.54

Using the following code, I can generate a plot:

idx <- 1:nrow(dt)
g <- ggplot(data = dt, aes(x = idx)) +
     geom_line(aes(y = col_A, group = 1, colour = "A"))
     geom_line(aes(y = col_B, group = 2, colour = "B")) +
     geom_vline(xintercept = dt[, .I[diff == max(diff)]], color = "black") +
     scale_color_manual(values = c("A" = "red", "B" = "blue") 
g

plot

But the above black line is not what I want. What I want is to cap this line using the blue and red ones, and add a text label to display the maximum difference, like this: true plot

How can I realize this? Thank you


Solution

  • You could use geom_textsegment from geomtextpath here:

    library(geomtextpath)
    
    ggplot(data = dt, aes(x = idx, y = col_A)) +
      geom_line(aes(group = 1, colour = "A")) +
      geom_line(aes(y = col_B, group = 2, colour = "B")) +
      geom_textsegment(data = dt[which.max(dt$diff),], 
                   aes(yend = col_B, xend = idx, label = round(diff, 3))) +
      scale_color_manual(values = c("A" = "red", "B" = "blue"))
    

    enter image description here


    Data used

    The example data in the question was insufficient for a demo, so here is the reproducible set used for the above example:

    set.seed(1)
    
    dt <- data.frame(time = 1:100, 
                     col_A = cumsum(runif(100, -5, 5)), 
                     col_B = cumsum(runif(100, -5, 5)) + 50)
    
    dt$diff <- dt$col_B - dt$col_A
    dt$idx  <- seq(nrow(dt))