Brian Fisher
Brian Fisher

Reputation: 1367

Plotting multiple years with ggplot across Jan1 r

I am trying to plot several years of data that crosses Jan 1, on ggplot in r, and want to have the series line up. If the period of interest didn't cross Jan 1, I could create variable for plotting where all the years were set to the same value, using something like:

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

Dates = ymd(c("2018-08-01", "2018-09-15", "2018-11-20", "2019-01-15", "2019-03-15", "2019-08-15", "2019-09-20", "2019-12-02", "2020-01-15", "2020-03-20" ))
Values = rep(c(15, 14, 10, 8, 4), times = 2)
Period = rep(c("Before", "After"), each = 5)

my_df = data.frame(Dates, Values, Period)

my_df = my_df %>%
      mutate(plot.date = `year<-`(Dates, 2020))

my_df %>%
      ggplot(aes(x = plot.date, y = Values, color = Period))+
      geom_line()
      

But this breaks the series in the wrong spot.
not what I want

I'm looking for something more like this, which I achieved by manually changing the years in the second set to match the first.

What I want

I also tried using the original dates and facets, but this isn't great because the start and end dates for the series are different (August 1 and March 1 vs. August 23 and March 23), so with scales = "free_x" they don't line up.

my_df %>%
      ggplot(aes(x = Dates, y = Values))+
      geom_line()+
      facet_wrap( ~ Period, ncol = 1, scales = "free_x")

Works, but not great because the dates don't line up:

poorly aligned facets

Upvotes: 1

Views: 907

Answers (1)

Sinh Nguyen
Sinh Nguyen

Reputation: 4487

Not fully sure what you want to with scales = "free_x" but another way to achieve the 2nd graph is to calculate days to Jan 1st and plot data with some markup labels.

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

graph_data <- my_df %>%
  group_by(Period) %>%
  mutate(jan_first = as.Date(paste0(year(max(Dates)), "-01-01"))) %>%
  mutate(days_diff_jan_first = as.numeric(difftime(Dates, jan_first, units = "days")))


breaks <- as.numeric(difftime(seq(as.Date("2018-06-01"), as.Date("2019-05-01"),
  by = "1 month"),
  as.Date("2019-01-01"), units = "days"))
labels <- c("Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "Jan", "Feb", "Mar",
  "Apr", "May")


ggplot(data = graph_data) +
  geom_line(mapping = aes(x = days_diff_jan_first, y = Values, color = Period)) +
  scale_x_continuous(breaks = breaks, labels = labels) +
  xlab("Month")

Created on 2021-04-30 by the reprex package (v2.0.0)

Upvotes: 1

Related Questions