RGRGRG
RGRGRG

Reputation: 1079

Scale the x-axes with quarterly date format

I created a plot in R using the ggplot library:

library(ggplot2)
ggplot(df, aes(x = yQ, y = value, group =1)) +
geom_line(aes(color = variable), size = 1) +
   scale_color_manual(values = c("#00AFBB", "#E7B800"))

I got the plot that I want but the only problem is that variable, yQ values have the format:

 1990Q1
 1900Q2
 1990Q3
 1990Q4
 ......
 ......
 2017Q1
 2017Q2
 2017Q3
 2017Q4

and because there are many years, the x-axis label cannot show all the dates clearly (they overlapped). Therefore, I want the x-axis label to show only Q1 and Q3 for every 5 years. So I want the x-axis to be something like this:

    1990Q1   1990Q3   1995Q1   1995Q3 ......  2015Q1 2015Q3

I tried to use scale_x_date but my dates are not in date format (e.g. 1990Q1) and therefore this does not work. How can I fix it?

Upvotes: 3

Views: 4582

Answers (4)

chandler
chandler

Reputation: 846

The zoo::format.yearqtr() function is quite easy to use with ggplot2.

Try

scale_x_date(labels = function(x) zoo::format.yearqtr(x, "%YQ%q"))

Upvotes: 4

G. Grothendieck
G. Grothendieck

Reputation: 269586

The question does not provide reproducible input but using df from the Note below with the autoplot.zoo method of ggplot's autoplot generic we can write:

library(ggplot2)
library(zoo)

z <- read.zoo(df, index = "yQ", FUN = as.yearqtr)
autoplot(z) + scale_x_yearqtr()

Note

Test input--

df <- data.frame(yQ = c("1990Q1", "1990Q2", "1990Q3", "1990Q4"), value = 1:4)

Upvotes: 3

CPak
CPak

Reputation: 13581

You can

  • manipulate x-axis breaks and labels with scale_x_discrete(breaks = ..., labels = ...)
  • change the angle of text with theme(axis.text.x = element_text(angle = ...))

I generated some data

Combs <- expand.grid(1990:2017, c("Q1", "Q2", "Q3", "Q4"))
df <- data.frame(
    yQ = sort(apply(Combs, 1, paste, collapse="")),
    value = runif(112)
)

In the first example, I subset yQ values you want with a logical vector - and change the angle of text

library(ggplot2)
pattern <- c(T, F, T, F, rep(F, 16))
ggplot(df, aes(x = yQ, y = value, group =1)) +
geom_line(aes(color = "red"), size = 1) +
scale_x_discrete(breaks = df$yQ[pattern], labels = df$yQ[pattern]) +
theme(axis.text.x = element_text(angle=90))

But notice that ticks marks not specified by break are not shown - so the alternative is to copy yQ values into a vector and make non-relevant years = ""

xVec <- as.character(df$yQ)
xVec[pattern==F] <- ""
ggplot(df, aes(x = yQ, y = value, group =1)) +
geom_line(aes(color = "red"), size = 1) +
scale_x_discrete(breaks = df$yQ, labels = xVec) +
theme(axis.text.x = element_text(angle=90))

Upvotes: 0

pogibas
pogibas

Reputation: 28339

Use function zoo::as.yearqtr (zoo package) to work with quarterly dates.

Generate example data:

year <- 1990:2000
quar <- paste0("Q", 1:4)
foo <- as.vector(outer(year, quar, paste0))
data <- data.frame(dateQ = foo, Y = rnorm(length(foo)))
head(data)

   dateQ           Y
1 1990Q1 -0.09944705
2 1991Q1  0.14493910
3 1992Q1  0.54856787
4 1993Q1  1.12966224
5 1994Q1 -0.93539302
6 1995Q1  0.24772265

Transform quarterly date to "normal" date:

data$dateNorm <- as.Date(zoo::as.yearqtr(data$dateQ))
head(data)
   dateQ           Y   dateNorm
1 1990Q1 -0.09944705 1990-01-01
2 1991Q1  0.14493910 1991-01-01
3 1992Q1  0.54856787 1992-01-01
4 1993Q1  1.12966224 1993-01-01
5 1994Q1 -0.93539302 1994-01-01
6 1995Q1  0.24772265 1995-01-01

It sets Q1/2/3/4 as the first day of January/April/July/October.

data[grep("1991", data$dateQ), ]
    dateQ          Y   dateNorm
2  1991Q1  0.1449391 1991-01-01
13 1991Q2  1.5878678 1991-04-01
24 1991Q3 -0.1071823 1991-07-01
35 1991Q4  2.2905729 1991-10-01

Now you can plot it or perform other calculations as it's in Date format.

library(ggplot2)
ggplot(data, aes(dateNorm, Y)) +
    geom_line()

enter image description here

Upvotes: 1

Related Questions