Panel Charts without Text Annotation

Introduction

This tutorial shows how to make a panel chart in ggplot.

We will use data for Jamaica from the Penn World Table.

Prerequisites

Firstly, we load the required R packages for our data analysis and visualization:

  • haven: To read in datasets stored in Stata file format (.dta).
  • dplyr: To manipulate data efficiently.
  • ggplot2: To create sophisticated visualizations.
  • here: To construct file paths.

We also source a custom script which defines the IMF theme.

library(haven)
library(dplyr)
library(ragg)
library(ggplot2)
library(ggpubr)
library(here)
library(gridExtra)
library(patchwork)
library(textshaping)

source(here("utils/theme_and_colors_IMF.R"))

Data Loading and Transformation

We read the dataset pwt100.dta which is stored under the “databases” directory. The here function ensures the file path is set up correctly regardless of where the project folder resides within the R-project.

penn <- read_dta(here("databases/pwt100.dta"))

Filter the dataset for the country Jamaica by its code “JAM”. After filtering, we calculate several new columns that represent different economic metrics:

  • kl: Capital per worker.
  • yl: GDP per worker (labor productivity).
  • ypop: GDP per capita.
  • ky: Capital-output ratio.
  • lpop: Employment-to-population ratio.
jam <- penn %>% filter(countrycode == "JAM") %>%
  mutate(kl=0.001*rnna/emp,
         yl=0.001*rgdpna/emp,
         ypop=0.001*rgdpna/pop,
         ky=rnna/rgdpna,
         lpop=emp/pop
         ) %>%
  select(year,kl,yl,ypop,ky,lpop,irr,rtfpna)

jam
# A tibble: 70 × 8
    year    kl    yl  ypop    ky   lpop     irr rtfpna
   <dbl> <dbl> <dbl> <dbl> <dbl>  <dbl>   <dbl>  <dbl>
 1  1950  NA    NA   NA    NA    NA     NA       NA   
 2  1951  NA    NA   NA    NA    NA     NA       NA   
 3  1952  NA    NA   NA    NA    NA     NA       NA   
 4  1953  76.9  11.2  4.26  6.83  0.379  0.126   NA   
 5  1954  79.2  12.5  4.67  6.36  0.375  0.132   NA   
 6  1955  81.9  13.6  5.06  6.01  0.371  0.117   NA   
 7  1956  85.3  15.0  5.51  5.69  0.368  0.0812  NA   
 8  1957  90.2  16.8  6.11  5.37  0.364  0.0884   1.14
 9  1958  94.2  17.1  6.14  5.52  0.360  0.0949   1.15
10  1959  97.2  17.4  6.21  5.57  0.356  0.0815   1.15
# ℹ 60 more rows

Plotting Function

A custom function makeFigure is created to plot the data. It takes a title and a variable and returns a ggplot object. This function makes use of the theme_imf() from the sourced script to apply the IMF styling to the plots.

makeFigure <- function(title, var) {
  jam %>% 
    ggplot(aes(x = year, y = {{var}})) +
    geom_path(linewidth  = 1.5, colour = blue) +
    scale_x_continuous(limits = c(1950, 2020), breaks = seq(1950, 2020, 10)) +
    ggtitle(title) +
    labs(x = "", y = "") +
    theme_imf_panel()
}

Generating and Customizing Plots

We call makeFigure multiple times to create different plots for each economic indicator. We then further customize each plot, particularly adjusting the y-axis scale to fit the data.

figypop <- makeFigure("GDP Per Capita", ypop)
figypop <- figypop + scale_y_continuous(limits = c(4.5, 9.5), 
                                        breaks = seq(4.5, 9.5, 1), expand = c(0, 0))

figypop<-makeFigure("GDP Per Capita",ypop)
figypop  <- figypop + scale_y_continuous(limits = c(4.5,9.5), 
                                         breaks = seq(4.5,9.5,1),expand = c(0,0))

figyl<-makeFigure("Labor Productivity",yl)
figyl <- figyl + scale_y_continuous(limits = c(10,30), 
                                    breaks = seq(10,30,5),expand = c(0,0))

figlpop<-makeFigure("Employment-to-Population Ratio",lpop)
figlpop <- figlpop + scale_y_continuous(limits = c(0.3,0.5), 
                                        breaks = seq(0.3,0.5,0.05),expand = c(0,0))

figkl<-makeFigure("Capital Per Worker",kl)
figkl <- figkl + scale_y_continuous(limits = c(70,160), 
                                    breaks = seq(70,160,150),expand = c(0,0))

figtfp<-makeFigure("TFP",rtfpna)
figtfp <- figtfp + scale_y_continuous(limits = c(0.95,1.5), 
                                      breaks = seq(1,1.5,0.1),expand = c(0,0))

figky<-makeFigure("Capital-Output Ratio",ky)
figky <- figky + scale_y_continuous(limits = c(5,7.5), 
                                    breaks = seq(5,7,0.5),expand = c(0,0))

figirr<-makeFigure("Internal Rate of Return",irr)
figirr <- figirr + scale_y_continuous(limits = c(0.03,0.14), 
                                      breaks = seq(0.03,0.14,0.02),expand = c(0,0))

Combining and Annotating the Plots

The patchwork package is used to combine the individual plots into a composite figure. We then annotate the combined figure with a title, subtitle, and caption.

pw <- (figypop) /
  (figyl| figlpop)  /
  (figkl| figtfp)  /
  (figky| figirr)  

pw <- pw + plot_annotation(
  title = 'Figure 1. Jamaica: Real GDP and Production Factors', 
  subtitle = '(In thousands of constant US dollars)',
  caption="Sources: Penn World Tables 10 and IMF staff calculations.",
  
  theme = theme(plot.title = element_text(color=blue,family=primary_font,face="bold",
                                          hjust=0.5,
                                          size=20),
                
                plot.subtitle = element_text(color=blue,family=primary_font,face = "plain",
                                             hjust=0.5,
                                             size=20),
                plot.caption = element_text(hjust = 0,size=12,family=primary_font)
  ))


pw

Saving the Figure

Finally, we save the annotated figure to a PNG file with a resolution of 600 DPI.

ggsave(here("figures/panel-figure-02-jam-real-gdp-prod-factors.png" ),  
       plot = pw, dpi =600,  width = 12.51,
       height = 15.64 ,  units = "in")