How to show date x-axis labels every 5 years in ggplot2

115 Views Asked by At

I generate a plot with the code below:

filtered_data |>
     filter(geo != "AT" & geo != "HU" & geo != "ES") |>
     ggplot(aes(x = TIME_PERIOD, y = OBS_VALUE, group = geo, color = geo))+
     geom_line()+
     geom_line(data = filter(filtered_data, geo %in% c("AT", "HU", "ES")), linewidth = 1.2)+
     scale_color_manual(values = c("AT" = "darkgoldenrod", "HU" = "darkred", "ES" = "darkgreen"))+
     geom_text(data = last_values |> filter(geo %in% c("AT", "HU", "ES")), 
            aes(label = ifelse(geo %in% c("AT", "HU", "ES"), paste(OBS_VALUE, "%", sep = ""), OBS_VALUE)), 
            hjust = 0, vjust = -0.5)+
     guides(color = "none")+
     scale_x_discrete(expand = expansion(add = c(0, 10)))+
     scale_y_continuous(labels = label_percent(scale = 1))+
     labs(x = "", y = "", 
       title = "Inflation in the European Union", 
       subtitle = "Annual change in the Harmonized Consumer Prices Index 2010-2022", 
       caption = "Source: Eurostat. Figure: Darius Markovskij")+
     theme_minimal()+
     theme(panel.grid.minor = element_blank())

enter image description here

But as you can notice the dates labels in x-axis are too dense, so what should I do if I wany to display date labels by 5 years (only 2010, 2015 and 2020). The values from TIME_PERIOD are with format %Y-%m-%d.

How could I do that? Thanks.

I tried to convert TIME_PERIOD from character to date using this


filtered_data$TIME_PERIOD <- as.Date(filtered_data$TIME_PERIOD, format = "%Y-%m-%d")

However, when I enter this data to my ggplot(), then the follwoing error message occurs - Error: Invalid input: date_trans works with objects of class Date only.

1

There are 1 best solutions below

0
On

I assume that your data looks like this after you converted filtered_data$TIME_PERIOD from class "character" to class "Date":

filtered_data <- data.frame(TIME_PERIOD = seq(as.Date("2010-01-01"),
                                          as.Date("2020-12-01"),
                                          by = "1 month"))

filtered_data$OBS_VALUE <- c(1:length(filtered_data$TIME_PERIOD)) # generates some dummy numbers

Please check for your data if filtered_data$TIME_PERIOD really has class `"Date" by running:

class(filtered_data$TIME_PERIOD) # must return "Date"

Replacing scale_x_discrete() by scale_x_date() with date_breaks = "5 years" should then result in the desired breaks of the x-axis:

library(ggplot2)

ggplot(data = filtered_data, aes(x = TIME_PERIOD, y = OBS_VALUE)) +
  scale_x_date(expand = expansion(add = c(0, 10)), date_breaks = "5 years")