Search code examples
rggplot2tidyversegeom-vline

ggplot - multiple different geom_vlines with differing lengths


I am trying to emulate the image shown where the vertical lines stop at the data points. Is there a way to give geom_vlines a specific length? I have included example code below to show what I have right now. I want each vline to stop when it intercepts a point.

enter image description here

library(tidyverse)
library(lubridate)
library(scales)

dates <- c("2021-01-01", "2021-02-01", "2021-03-01")
values <- c(1,2,3)
df <- data.frame(dates, values)
df <- df %>% 
  mutate(dates = date(dates))

df %>% 
  ggplot(aes(dates, values)) +
    geom_point() +
    theme_minimal() +
    scale_y_continuous(limits = c(0,3)) +
    theme(
      panel.grid.minor.y = element_blank(),
      panel.grid.major.x = element_blank(),
      panel.grid.minor.x = element_blank(),
      axis.title.x = element_blank(),
      axis.title.y = element_blank()
    ) +
    geom_vline(xintercept = as.numeric(as.Date("2021-01-01"))) +
    geom_vline(xintercept = as.numeric(as.Date("2021-02-01"))) +
    geom_vline(xintercept = as.numeric(as.Date("2021-03-01")))

Solution

  • You can do this using geom_segment instead of geom_vline.

    df %>% 
      ggplot(aes(dates, values)) +
      geom_point() +
      geom_segment(aes(x = dates, xend = dates, y = 0, yend = values), color = "red") + 
      theme_minimal() +
      scale_y_continuous(limits = c(0,3)) +
      theme(
        panel.grid.minor.y = element_blank(),
        panel.grid.major.x = element_blank(),
        panel.grid.minor.x = element_blank(),
        axis.title.x = element_blank(),
        axis.title.y = element_blank()
      )
    

    Result:

    enter image description here