Home > Software engineering >  Add hline for groups outside of aestetic in ggplot
Add hline for groups outside of aestetic in ggplot

Time:11-18

I have a line chart with metrics for different years and months. I want to add a median line for each month.

library(dplyr)
library(lubridate)
library(ggplot2)

set.seed(52)

data <- tibble(
  date = seq.Date(from = as.Date("2017-01-01"), to = date("2020-12-31"), by = "month")
) %>% 
  mutate(
    metric = rnorm(n(), mean = 5, sd = 2),
    month = month(date, label = TRUE),
    year = as.factor(year(date))
  )

ggplot(data, aes(x = month, y = metric, color = year, group = year))  
  geom_line()

I tried using geom_hline() to do this but it only produces a line for the total median.

ggplot(data, aes(x = month, y = metric, color = year, group = year))  
  geom_line()  
  geom_hline(aes(yintercept = median(metric), group = month))

Created on 2021-11-18 by the enter image description here

CodePudding user response:

Is this what you are looking for...?

ggplot(data, aes(x = month, y = metric, color = year, group = year))  
     geom_line()  
     geom_tile(data = function(df) df %>% group_by(month) %>% 
                                          summarise(metric = median(metric)),
               aes(x = month, y = metric), height = 0.05, inherit.aes = FALSE)

enter image description here

Alternatively, thanks to @user20650's comment below, this also works...

ggplot(data, aes(x = month, y = metric, color = year, group = year))  
     geom_line()  
     stat_summary(aes(x = month, y = metric), 
                  fun = median, 
                  geom = "tile", 
                  height = 0.05, 
                  inherit.aes = FALSE)

CodePudding user response:

Not sure if this is what you're looking for, but you can simply create a new variable in your dataset with a median metric. Your first group observations by month, then calculate a median metric and then ungroup the data.

data <- data %>% group_by(month) %>% mutate(median_metric=median(metric)) %>% ungroup()

Once you do it, you just specify yintercept to vary by median_metric

ggplot(data )   
  geom_line(aes(x = month, y = metric, color = year, group = year)) 
  geom_hline(aes(yintercept = median_metric))

CodePudding user response:

You could use ave.

I didn't get it if you need a median line for each year or through the months, so I will show you both.


Median for each year

ggplot(data, aes(x = month, y = metric, color = year, group = year))  
   geom_line()  
   geom_line(aes(y = ave(metric, year, FUN = median)))

enter image description here


Median through months

ggplot(data, aes(x = month, y = metric, color = year, group = year))  
  geom_line()  
  geom_line(aes(y = ave(metric, month, FUN = median), colour = "median"), size = 2)

enter image description here


EDIT:

since you are interested in a horizontal line, here you have an alternative solution:

ggplot(data, aes(x = month, y = metric, color = year, group = year))  
  geom_line()  
  stat_summary(aes(x = month,  y=metric), fun = median, geom = "point", shape = "-", size = 15, inherit.aes = FALSE)

  • Related