3

I need to make several time-series graphs in the same format as shown in Fig. I'm interested in the format itself.

I will be grateful for your help.

enter image description here

Here a minimal example with simulated data

    set.seed(1234)
    nobs<-50
    x<-rnorm(nobs,0,10)
    t<-seq(1,nobs)
    data<-ts(20+x+t, freq=4, start=c(2004,1))
    par(family="serif")
    plot(data, lwd=2, col="blue4", ylab="Millions")
    title(main="Gráfico 1. Evolución del ...")
    legend(2010,10,"GDP", col="blue4",lwd=2)
    abline(lm(data~t), lwd=2, col="red") # This does not work 

enter image description here

Héctor Garrido
  • 185
  • 1
  • 14

2 Answers2

6

I assume that your data is a ts object, as in your example. Here is an approach using base graphics. We start off with a minimal plot, then layer on elements. First, the minimal plot, making sure to leave lots of space at side 1 (i.e. bottom):

par(mar = c(8, 4, 4, 2), family = "serif", las = 1)
plot(data, 
  frame = FALSE,
  xaxt = "n", 
  ylab = "Millones de pesos", xlab = "", 
  main = "Gráfico 1. Evolución del ...",
  col = "darkblue", lwd = 2)
fit <- forecast::tslm(data ~ trend)
lines(fitted(fit), col = "red", lwd = 2)

Note that above, we use forecast::tslm to get the time trend for the time series. Now, add the x-axis elements. I use mtext to insert the tick labels:

axis(1, at = seq(2003.875, 2015.875, 1), tck = -.2, labels = FALSE)
mtext(rep(c("ener-mar", "abril-jun", "jul-sep", "oct-dic"), l = length(data)),
  side = 1, line = 0.25, las = 2,
  at = seq(tsp(data)[1], tsp(data)[2], by = 1/tsp(data)[3]),
  cex = .6)
mtext(2004:2016, side = 1, line = 3, at = seq(2004.3, 2016.3), cex = .7)
title(xlab = "Trimestres", line = 5, cex.lab = .8)

Finish off with the legend:

par(xpd = TRUE)
legend(2010, -27, c("PIB", "Tendencia PIB"), 
  bty = "n",
  xjust = .5,
  lty = c(1, 1),
  col = c("darkblue", "red"),
  cex = .7,
  horiz = TRUE)

Output: enter image description here

Weihuang Wong
  • 12,868
  • 2
  • 27
  • 48
3

Here's a ggplot2 approach that comes close to the plot format in your question:

library(ggplot2)

# Fake data
set.seed(1234)
nobs<-52
t<-seq(1,nobs)
x<-rnorm(nobs,0,10) + t + 20
dat = data.frame(year=rep(2004:2016, each=4), qtr=rep(1:4, 13), x = x)

ggplot(dat, aes(paste(year,qtr), x)) +
  geom_vline(xintercept=seq(4.5,100,4), colour="grey80",lwd=0.3) +
  geom_line(aes(group=1)) +
  annotate(seq(2.5, 2.5 + 12*4, length.out=13), -2, label=2004:2016, 
           geom="text", colour="grey30", size=3.5) +
  theme_bw(base_size=10) +
  theme(axis.text.x=element_text(angl=-90, vjust=0.5, colour="grey30"),
        panel.grid.major.x=element_blank()) +
  scale_x_discrete(name="Quarter",
                   labels=rep(paste0(month.abb[seq(1,12,3)],"-",month.abb[seq(3,12,3)]),20)) +
  coord_cartesian(xlim=c(0,13*4 + 1), ylim=c(-4,max(dat$x + 2)), expand=FALSE) 

enter image description here

Facetting comes closer to the formatting you wanted, but there's no way (AFAIK) within the normal ggplot workflow to connect lines across the facets. In the plot below, the vertical lines show the borders between each facet. There are (somewhat complicated) ways to try and connect lines across facets, but I didn't make it that far in the example below.

dat$qtr = rep(paste0(month.abb[seq(1,12,3)],"-",month.abb[seq(3,12,3)]),13)
dat$qtr = factor(dat$qtr, levels=paste0(month.abb[seq(1,12,3)],"-",month.abb[seq(3,12,3)]))

p=ggplot(dat, aes(qtr, x)) +
  geom_line(aes(group=1)) +
  coord_cartesian(xlim=c(0.5,4.5), expand=FALSE, ylim=c(-2,80)) +
  facet_grid(. ~ year, switch="x") +
  annotate(x=c(0.5, 4.5), xend=c(0.5,4.5), y=-16, yend=-2, geom="segment", 
           colour="grey70", size=0.3) +
  theme_bw(base_size=10) +
  theme(panel.margin=unit(0,"lines"),
        axis.text.x=element_text(angl=-90, vjust=0.5, colour="grey30"),
        panel.border=element_rect(colour="grey70", size=0.3),
        panel.grid.major=element_blank(),
        strip.background=element_rect(fill="grey90", colour="grey20"),
        axis.line=element_line(colour="black")) +
  labs(x="Quarter")

# Turn off clipping and draw plot
gt <- ggplot_gtable(ggplot_build(p))
gt$layout$clip[gt$layout$name=="panel"] <- "off"
grid.draw(gt)

enter image description here

Community
  • 1
  • 1
eipi10
  • 91,525
  • 24
  • 209
  • 285