Times Series Plots with ggplot2

ggplot2 enables us to make beautiful graphics (as long as you use the tidyverse framework)

Paulo Ferreira Naibert https://github.com/pfnaibert/
2020-08-20

Last Updated 2020-09-03

On previous posts (here and here ), I demonstrated how to import and graph data using R. On this post, I will make those same plots using ggplot2 to make beautiful plots. First we will need to load the data and the functions.


# funs
source("./myfuns.R")

# import data
y    <- import_gdp("../../data/PIB_BASE_2000.csv")
recs <- readRDS("../../data/gdp-recessions.rds")

# transform dates
dates <- date2num(names(y))
recs  <- date2num(recs)

# quick visualizations
head(y); head(dates); head(recs)

1980:Q1 1980:Q2 1980:Q3 1980:Q4 1981:Q1 1981:Q2 
   70.6    76.3    75.5    73.2    70.5    74.3 

[1] 1980.00 1980.25 1980.50 1980.75 1981.00 1981.25

[1] 1981.0 1983.0 1987.5 1988.5 1989.5 1992.0

Now, let’s load the ggplot2 library and make some graphs.


# libraries
library(ggplot2)

# expected plot
ggplot(y)

Error: `data` must be a data frame, or other object coercible by `fortify()`, not an S3 object with class ts

Wait, WHAT? Why didn’t that work? I mean, plot(y), should work:


# base plot
plot(y)

And it DOES, with the labels working properly and we don’t even have to specify the type (which should be line). So why ggplot2 does not? Let’s read the error message, as we should have, from the beginning. OK, OK, We will have to convert our data to a data.frame, a bit cumbersome, but hey, this is a FANCY package.


y.df  <- as.data.frame(cbind(dates, "GDP"=y) )
head(y.df)

    dates  GDP
1 1980.00 70.6
2 1980.25 76.3
3 1980.50 75.5
4 1980.75 73.2
5 1981.00 70.5
6 1981.25 74.3

# plot
ggplot(y.df)

It is just a BLANK plot?! OMG! Let’s just RTFM already and get it over with.

I used the following links (because internet is better than books?):

So, ggplot2 has its very own syntax (grammar?), but it does have a quick plot option, let’s try it now:


# quick plot
qplot(x=dates, y=GDP, data=y.df,
      geom="line", size=I(1), color = I("blue"),
      xlab="", ylab="",
      main = "Cronologia Trimestral dos Ciclos de Negócios Brasileiros" )

OK, that’s a nice enough looking plot, let’s try the ggplot function (again, the package has it’s own grammar):


# plot
ggplot(data = y.df, aes( x = dates, y = GDP ) ) +
    theme( plot.title = element_text(hjust = 0.5, face = "bold" ) ) +
    ggtitle( "Cronologia Trimestral dos Ciclos de Negócios Brasileiros" ) +
    xlab("") + ylab("") +
    geom_line( color = "blue", size=1 )

For the title options I used the following links:

Figures inside the plot

Cool, but what about abline() and rect()?

abline()

For straigh lines in the plot, the ggplot() syntax is actually pretty intuitive, below we show an example:


ggplot(data = y.df, aes( x = dates, y = GDP ) ) +
    theme( plot.title = element_text(hjust = 0.5, face = "bold" ) ) +
    ggtitle( "Cronologia Trimestral dos Ciclos de Negócios Brasileiros" ) +
    xlab("") + ylab("") +
    geom_line( color = "blue", size=1 ) +
    geom_vline( color = "red", linetype="dotted", size=.5, aes( xintercept=1990 ) ) +
    geom_hline( color = "red", linetype="dashed", size=.5, aes( yintercept=100 ) )

rect()

NICE! Now I want to make a rectangle to highlight the recession periods. The plot worked just fine when I used a single rectangle, but it would not work if I used a for loop to make more rectangles. To figure out how to make more rectangles, I used this page. Let’s show our work.


# tranform recs to data frame
recs.mat <- as.data.frame( t( matrix( recs, nrow=2 ) ) ); colnames(recs.mat) <- c("start", "end")

# plot with rect
ggplot(data = y.df, aes( x = dates, y = GDP ) ) +
    theme( plot.title = element_text(hjust = 0.5, face = "bold" ) ) +
    ggtitle( "Cronologia Trimestral dos Ciclos de Negócios Brasileiros" ) +
    xlab("") + ylab("") +
    geom_rect( data=recs.mat, aes( NULL, NULL, xmin = start, xmax = end ), ymin = 0, ymax = 200 ) +
    geom_line( color = "blue", size=1 )

And there you have it, I made the plot with ggplot().

Plot Objects

One neat thing about ggplot() is that we can “save” a plot as an object. We can use this to customize the plot later.


# save plot
gdp_plot  <-
ggplot(data = y.df, aes( x = dates, y = GDP ) ) +
    ggtitle( "Cronologia Trimestral dos Ciclos de Negócios Brasileiros" ) +
    xlab("") + ylab("") +
    geom_line( color = "blue", size=1 )

# list objects
ls()

[1] "date2num"   "dates"      "gdp_plot"   "import_gdp" "qtr2date"  
[6] "recs"       "recs.mat"   "y"          "y.df"      

Let’s plot it.


# plot gdp_plot
gdp_plot

Let’s center the title.


# save gdp_plot with centered title
gdp_plot_center <- gdp_plot +
theme( plot.title = element_text(hjust = 0.5, face = "bold" ) )

gdp_plot_center

Let’s add the rectangles.


gdp_plot_center +
geom_rect( data=recs.mat, aes( NULL, NULL, xmin = start, xmax = end ), ymin = 0, ymax = 200)

Yes, we messed up the order of the arguments in this last one. But hey, the saving plots feature worked. Let’s change the alpha argument to make transparent rectangles (I should’ve done it from the beginning)


p <- gdp_plot_center +
geom_rect( data=recs.mat, aes( NULL, NULL, xmin = start, xmax = end ), ymin = 0, ymax = 200, alpha = .3 )

# plot
p

Themes

We can see that customizing graphs is ggplot2’s strong suit, there is even a package with different themes to make them even more beautiful. Let’s try it.


library(ggthemes)

# theme bw
ggplot(data = y.df, aes( x = dates, y = GDP ) ) +
    theme_bw() +
    theme( plot.title = element_text(hjust = 0.5, face = "bold" ) ) +
    ggtitle( "Cronologia Trimestral dos Ciclos de Negócios Brasileiros" ) +
    xlab("") + ylab("") +
    geom_line( color = "blue", size=1 )

And now, the long waited theme_economist():


# theme economist
ggplot(data = y.df, aes( x = dates, y = GDP ) ) +
    theme_economist() +
    ggtitle( "Cronologia Trimestral dos Ciclos de Negócios Brasileiros" ) +
    xlab("") + ylab("") +
    geom_line( color = "blue", size=1 )

And yes, the themes work with saved objects


gdp_plot


gdp_plot + theme_bw()


gdp_plot + theme_economist()

Final Remarks

ggplot2 is a phenomenal package once you jump through the initial hurdles. The problem with ggplot2 is that by having its own grammar the novice R user will not learn the R syntax, and the more experienced user will not benefit from knowing the R syntax. Those problems arise because the package is its own animal, but also because of this it is almost infinitely customizable. It should definitely be the choice if you intend to make beautiful polished plots. If you just want to make a quick plot to visualize some data and forget about the plot, your are better served with the base plots.

But again, therein lies another problem, you will use two different GRAMMARS to make plots. The base to make your quick and dirty plots. And ggplot’s to make a finished product. That is a question that tears me apart, and honestly I cannot decide if the tradeoff is worth. But hey, I’m using the package, am I not? So maybe, I have my answer.

Corrections

If you see mistakes or want to suggest changes, please create an issue on the source repository.