donman
donman

Reputation: 67

How to create custom date labels using ggplot with scale_x_date

When I use date_labels = “%b %y” within scale_x_date then the tick labels are rather cluttered because the year appears with each month. (I specifically want to label every month.) I would rather have the year appear only at the start and end of the date range, and also at December and January.

My minimal representative example follows. I was hoping to use a function that creates the tick labels using date_labels = “%b %y” for December, January, first the month and the last month, and then to use date_labels = “%b” for all other months. As a first stab, I tried to reproduce my existing (cluttered) tick labels with a function (by switching to the commented line), but was not able to do so.

To be specific, for this example I would like tick labels to be Aug 20, Sep, Oct, Nov, Dec 20, Jan 21, Feb, Mar, Apr, May 21

Thank you for any suggestions.

start_date <- as.Date('2020-08-08')
end_date <- as.Date('2021-05-10')

# tibble with test data
mytib <- tibble( dates = as.Date(as.character(seq(start_date, end_date, by = 4) ) ), 
                 yval = as.numeric(strftime(dates, format = "%d")),
                 # following two lines just to give some color to the plot
                 month = strftime(dates, format = "%m") ) %>%
                 group_by( month ) 
  
gd <- 
  ggplot(mytib, aes( x=dates, y=yval, color = month ) ) +
  geom_point() +
  geom_line( aes( x=dates, y=yval, color=month, group=month ) ) +
  theme(legend.position = c("none")) +
  scale_x_date(date_breaks = "1 month", 
               date_minor_breaks = "1 week", 
               date_labels = "%b %y" )  + 
               #labels = function(x)  as.Date(x,format = "%b %y" ) )  + 
  labs (x=NULL, y=NULL ) +
  geom_blank()

gd

enter image description here

Upvotes: 0

Views: 1976

Answers (1)

Ronak Shah
Ronak Shah

Reputation: 388982

I am not sure if it is possible to provide such customised labels with scale_x_date. You can create them with dplyr and use scale_x_discrete.

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

mytib %>%
  arrange(dates) %>%
  mutate(month = month(dates), 
         year = year(dates)) %>%
  group_by(year, month) %>%
  mutate(labels = ifelse(row_number() == 1, format(dates, '%b'), '')) %>%
  group_by(year) %>%
  mutate(labels = ifelse(!duplicated(month) & month %in% range(month), 
                         format(dates, '%b %y'), labels)) %>%
  ungroup %>% 
  mutate(dates = factor(dates)) -> data


ggplot(data, aes( x=dates, y=yval, color = month)) +
  geom_point() +
  geom_line( aes( x=dates, y=yval, color=month, group=month ) ) +
  theme(legend.position = c("none")) + 
  scale_x_discrete(labels = data$labels)
  labs (x=NULL, y=NULL ) +
  geom_blank()

enter image description here

Upvotes: 2

Related Questions