josh
josh

Reputation: 73

How to annotate time periods on line plots with date axis?

I am looking to create a graph showing unemployment over the years and then adding in bars in the background of the plot highlighting periods of recession?

What code would I use for this? And do i need to use dates within the code?

Code I have tried is

ggplot(unemployment_data, aes(x=year, y=unemployment))+
geom_line

However, I am unsure if how I use geom_rect() and if that is the correct function to use? Similarly, when I go to the plot that ggplot as above, for some reason geom_line() doesn't work at appears with the error message "geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic" - how do I fix this?

Thanks for any help.

data

unemployment_data <- structure(list(year = c("1971 FEB", "1971 MAR", "1971 APR", "1971 MAY", "1971 JUN", "1971 JUL", "1971 AUG", "1971 SEP", "1971 OCT", "1971 NOV", "1971 DEC", "1972 JAN", "1972 FEB", "1972 MAR", "1972 APR", "1972 MAY", "1972 JUN", "1972 JUL", "1972 AUG", "1972 SEP"), unemployment = c(3.8, 3.9, 4, 4.1, 4.1, 4.2, 4.2, 4.3, 4.4, 4.4, 4.5, 4.5, 4.5, 4.5, 4.5, 4.4, 4.4, 4.3, 4.3, 4.2)), row.names = c(NA, -20L), class = c("tbl_df", "tbl", "data.frame"))

Upvotes: 1

Views: 1141

Answers (2)

tjebo
tjebo

Reputation: 23747

geom_rect is a good idea. And yes, using dates makes this much easier, because you won't have the trouble to sort your months and years in the right order. But working with dates can also be somewhat confusing.

I really recommend the lubridate package.

For the rectangles, create an extra data frame with the dates of start and end of recessions, see below.

Ah, and this warning that you got, you'll get rid of it with aes(group = 1)

library(tidyverse)
library(lubridate)

unemployment_data <- 
unemployment_data %>%
  mutate(date = as_date(parse_date_time(year, "ym")))

recession <- data.frame(date_start= as_date(c("1971-04-01", "1972-04-01")),
                        date_end = as_date(c("1971-07-01","1972-07-01")))

ggplot()+
  geom_rect(data = recession, aes(xmin = date_start, xmax = date_end, ymin = -Inf, ymax = Inf),
            fill = "red", alpha= 0.3)+
  geom_line(data = unemployment_data, aes(x=date, y=unemployment, group = 1)) +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  scale_x_date(date_breaks = "2 months")

Created on 2020-04-28 by the reprex package (v0.3.0)

Upvotes: 3

SNTag
SNTag

Reputation: 87

Why not overlay the graph over each other? You could add a separate geom_bar per dataset, with alpha for transparency. ex;

p <- ggplot(NULL, aes(x, y)) + 
  geom_bar(aes(fill = "year1"), data = year1, alpha = 0.5) +
  geom_bar(aes(fill = "year2"), data = year2, alpha = 0.5)

This assumes two dataframes (year1 and year2) with the data of interest, but this should show how you could apply it to your own data.

I would imagine that could get messy though. Might be better to use geom_bar(position="dodge"), I find it looks cleaner.

Upvotes: 2

Related Questions