library(readxl)
library(dplyr)
library(tidyr)
library(ggpubr)
library(here)
library(gridExtra)
library(patchwork)
library(ragg)
source(here("utils/theme_and_colors_IMF.R"))
source(here("utils/Add_text_to_figure_panel.R"))
Panel charts with text annotation
Introduction
This tutorial will guide you through the process of creating fiscal data visualizations using R. We will use several R packages to import, clean, and visualize fiscal data from Excel files.
Fiscal panel charts Jamaica
In this section we will show how to make panel charts with text annotation–the narrative on top of a individual panel charts that you often see in IMF staff reports.
Panel charts of Jamaica’s public finances
This tutorial will guide you through the process of creating panel charts of the public finances of Jamaica. This chart has appeared in the 2022 Jamaica staff report.
Setup
First, we load the required R libraries and source the custom functions that we will use throughout this tutorial.
Reading the Data
The data for our charts is stored across multiple sheets within an Excel workbook. We’ll read each sheet into its own R object.
<- read_excel(here("databases/SR charts v1.xlsx"), sheet = "Chart 1 Data")
chart_1_fiscal <- read_excel(here("databases/SR charts v1.xlsx"), sheet = "Chart 2 Data")
chart_2_fiscal <- read_excel(here("databases/SR charts v1.xlsx"), sheet = "Chart 3 Data")
chart_3_fiscal <- read_excel(here("databases/SR charts v1.xlsx"), sheet = "Chart 4 Data" )
chart_4_fiscal <- read_excel(here("databases/SR charts v1.xlsx"), sheet = "Chart 5 Data" )
chart_5_fiscal <- read_excel(here("databases/SR charts v1.xlsx"), sheet = "Chart 6 Data" ) chart_6_fiscal
Data Transformation
We need to transform our data into a long format that is suitable for plotting. We’ll define a function chart_long_fiscal
for this purpose and apply it to our datasets.
<- function(data){
chart_long_fiscal <- data %>%
output rename(label = Year) %>%
pivot_longer(-label,
names_to = "year",
values_to="value") %>%
mutate(year = as.numeric(year))
return(output)
}<- chart_long_fiscal(chart_1_fiscal)
chart_1_fiscal_long <- chart_long_fiscal(chart_2_fiscal)
chart_2_fiscal_long <- chart_long_fiscal(chart_3_fiscal)
chart_3_fiscal_long <- chart_long_fiscal(chart_4_fiscal)
chart_4_fiscal_long <- chart_long_fiscal(chart_5_fiscal)
chart_5_fiscal_long <- chart_long_fiscal(chart_6_fiscal)
chart_6_fiscal_long
rm(
chart_1_fiscal,
chart_2_fiscal,
chart_3_fiscal,
chart_4_fiscal,
chart_5_fiscal,
chart_6_fiscal )
Creating the Plots
With our data in the correct format, we can now create our visualizations using ggplot2
.
<-
fig_chart_1_fiscal %>%
chart_1_fiscal_long ggplot(aes(x = as.character(year),
y=value)) +
geom_bar(stat = "identity",
fill= blue,
position = position_dodge(0.73),
color = "black",
width = 0.42) +
geom_hline(aes(yintercept = 0),
color = light_grey,
linetype= "solid") +
scale_x_discrete(expand = c(0.05,0))+
scale_y_continuous(limits = c(-8,2),
breaks = seq(-8,2,2),
expand = c(0,0)) +
labs(title="Central Government Balance",
subtitle = "(In percent of GDP)",
# caption="Source: Bank of Jamaica (BOJ)",
x="", y= "")+
theme_imf_panel()
plot(fig_chart_1_fiscal)
<-
fig_chart_2_fiscal %>%
chart_2_fiscal_long ggplot(aes(x = year,
y= value,
color= label,
linetype = label))+
geom_line(linewidth =1.5)+
scale_x_continuous(limits =c(2010,2020), breaks = 2010:2020)+
scale_y_continuous(limits = c(24,34),
breaks = seq(24,34,2),
expand = c(0,0)) +
labs(title="Central Government Revenues and Expenditures",
subtitle = "(In percent of GDP)",
# caption="Source: Bank of Jamaica (BOJ)",
x="", y= "")+
scale_color_manual(values = c(blue,green)) +
scale_linetype_manual(values = c("solid","dashed")) +
theme_imf_panel()+
theme(legend.title = element_blank(),
legend.position = c(0.57,0.82),
# legend.direction = "vertical",
legend.background = element_blank(),
legend.key.height = unit(0.75, "cm"),
legend.key.width = unit(1.5, "cm"),
legend.spacing.x = unit(0.12,"cm"),
legend.spacing.y = unit(0.20, "cm"))
plot(fig_chart_2_fiscal)
<-
fig_chart_3_fiscal %>%
chart_3_fiscal_long filter(label != "Tax Revenue") %>%
ggplot(aes(x = as.character(year),
y=value,
fill = label)) +
geom_bar(stat = "identity",
position = "stack",
color = "black",
width = 0.42) +
scale_x_discrete(expand = c(0.05,0))+
scale_y_continuous(limits = c(0,30),
breaks = seq(0,30,5),
expand = c(0,0)) +
labs(title="Tax Revenue",
subtitle = "(In percent of GDP)",
# caption="Source: Bank of Jamaica (BOJ)",
x="", y= "")+
scale_fill_manual(values = c(green,blue)) +
theme_imf_panel()+
theme(legend.title = element_blank(),
legend.position = c(0.5,0.92),
legend.direction = "horizontal",
legend.background = element_blank(),
legend.key.height = unit(0.45, "cm"),
legend.key.width = unit(0.55, "cm"),
legend.spacing.x = unit(0.2,"cm"),
legend.spacing.y = unit(0.25, "cm"))+
guides(fill = guide_legend(label.hjust = 1))
plot(fig_chart_3_fiscal)
<-
fig_chart_4_fiscal %>%
chart_4_fiscal_long filter(label != "Current spending") %>%
ggplot(aes(x = as.character(year),
y=value,
fill = label)) +
geom_bar(stat = "identity",
position = "stack",
color = "black",
width = 0.42) +
scale_x_discrete(expand = c(0.05,0))+
scale_y_continuous(limits = c(0,35),
breaks = seq(0,35,5),
expand = c(0,0)) +
labs(title="Central Government Current Spending",
subtitle = "(In percent of GDP)",
# caption="Source: Bank of Jamaica (BOJ)",
x="", y= "")+
scale_fill_manual(values = c(green,blue)) +
theme_imf_panel()+
theme(legend.title = element_blank(),
legend.position = "inside",
legend.position.inside = c(0.5,0.9),
legend.direction = "horizontal",
legend.background = element_blank(),
legend.key.height = unit(0.45, "cm"),
legend.key.width = unit(0.55, "cm"),
legend.spacing.x = unit(0.25,"cm"),
legend.spacing.y = unit(0.20, "cm"))
fig_chart_4_fiscal
<-
fig_chart_5_fiscal %>%
chart_5_fiscal_long ggplot(aes(x = as.character(year),
y=value)) +
geom_bar(stat = "identity",
fill= blue,
position = position_dodge(0.73),
color = "black",
width = 0.42) +
geom_hline(aes(yintercept = 0),
color = light_grey,
linetype= "solid") +
scale_x_discrete(expand = c(0.05,0))+
scale_y_continuous(limits = c(0,5),
breaks = seq(0,5,1),
expand = c(0,0)) +
labs(title="Central Government Capital Spending",
subtitle = "(In percent of GDP)",
# caption="Source: Bank of Jamaica (BOJ)",
x="", y= "")+
theme_imf_panel()
plot(fig_chart_5_fiscal)
<- chart_6_fiscal_long %>%
chart_6_fiscal_long mutate(Year= as.character(year),
label_chart =
factor(label,
levels = c("Primary Balance (Lhs)"
"Debt (Rhs)"),
,labels= c("Primary Balance (top)",
"Debt (bottom)")))
<-
fig_chart_6_fiscal ggplot()+
geom_line(data= chart_6_fiscal_long %>%
filter(label != "Debt (Rhs)"),
aes(x= year,
y= value,
color = label_chart),
linewidth =1.5) +
geom_bar(data= chart_6_fiscal_long %>%
filter(label == "Debt (Rhs)"),
aes(x= year,
y= value,
fill = label_chart),
position = position_dodge(0.73),
color = "black",
width = 0.42,
stat = "identity") +
scale_x_continuous(limits =c(2009,2026.5),
breaks = 2010:2026,
expand = c(0,0.05)) +
scale_y_continuous( breaks= scales::extended_breaks(n=6),
limits = c(0, NA),
expand = expansion(mult = c(0,0.2))) +
labs(title="Primary Balance and Public Debt",
subtitle = "(In percent of GDP)",
# caption="Source: Bank of Jamaica (BOJ) and IMF Staff Estimates",
x="", y= "") +
scale_color_manual(values = c(blue)) +
scale_fill_manual(values = c(green)) +
facet_wrap(~label_chart,
scales= "free_y",
ncol = 1) +
theme_imf_panel()+
theme(strip.background = element_blank(), strip.text = element_blank(),
panel.spacing = unit(0.15, "lines"))+
theme(legend.title = element_blank(),
legend.position ="inside",
legend.position.inside = c(0.5,0.57),
# legend.direction = "vertical",
legend.box = "horizontal",
legend.background = element_blank(),
legend.key.height = unit(0.45, "cm"),
legend.key.width = unit(0.55, "cm"),
legend.spacing.x = unit(0.1,"cm"),
legend.spacing.y = unit(0.1, "cm"),
axis.text.x = element_text(angle = 45, hjust = 1, vjust = 0.95),
plot.margin = unit(c(0.5,1,0,0.5),"lines"))+
guides(color =guide_legend(order=2,
direction = "horizontal"),
fill = guide_legend(order=2,
direction = "horizontal"))
plot(fig_chart_6_fiscal)
<-
fig_chart_1_fiscal_text "The COVID-19 shock led to a sharp increase in central government's \nfiscal deficit and debt levels..."
<-
fig_chart_1_fiscal_panel AddTextToFigure(fig_chart_1_fiscal,fig_chart_1_fiscal_text)
<-
fig_chart_2_fiscal_text "...the revenue-to-GDP ratio declined and the expenditure-to-GDP \nratio increased."
<-
fig_chart_2_fiscal_panel AddTextToFigure(fig_chart_2_fiscal,fig_chart_2_fiscal_text)
<-
fig_chart_3_fiscal_text "Lower tax revenues in FY 2020 were the result of a decline in GDP and GCT\ntax cuts."
<-
fig_chart_3_fiscal_panel AddTextToFigure(fig_chart_3_fiscal,fig_chart_3_fiscal_text,0.58)
<-
fig_chart_4_fiscal_text "The increase in the spending ratio was largely the result of the decline in \nGDP."
<-
fig_chart_4_fiscal_panel AddTextToFigure(fig_chart_4_fiscal,fig_chart_4_fiscal_text,0.58)
<-
fig_chart_5_fiscal_text "While capital spending was held back to make room for COVID-19 \nrelated spending..."
<-
fig_chart_5_fiscal_panel AddTextToFigure(fig_chart_5_fiscal,fig_chart_5_fiscal_text,0.51)
<-
fig_chart_6_fiscal_text "...public debt rose in FY 2020 but is on a downward path to meet the FRL \ntarget."
<-
fig_chart_6_fiscal_panel AddTextToFigure(fig_chart_6_fiscal,fig_chart_6_fiscal_text,0.51)
Combining and Saving the Plots
Once all individual plots are created, we can combine them into a single figure layout using patchwork
.
<-
patchwork_layout_2 |fig_chart_2_fiscal_panel)/
(fig_chart_1_fiscal_panel|fig_chart_4_fiscal_panel)/
(fig_chart_3_fiscal_panel|fig_chart_6_fiscal_panel)
(fig_chart_5_fiscal_panel
<- patchwork_layout_2 + plot_annotation(
patchwork_output_2title = 'Figure 7. Fiscal Sector Developments',
# subtitle = '(In constant US dollars)',
caption="Sources: Bank of Jamaica and IMF staff estimates and projections.",
theme = theme(plot.title = element_text(color=blue,
family=primary_font,face="bold",
size=20, hjust = 0.5),
plot.subtitle = element_text(color="black",
family=primary_font,
face="plain",
hjust=0.5,
size=20),
plot.caption = element_text(hjust = 0,size=12,
family=primary_font,
),plot.margin = margin(0.75,0.5,0.5,0.5, "lines")
))
Finally, we save the combined plot to a file.
ggsave(
here("figures/panel-figure-2-fiscal.png"),
plot = patchwork_output_2,
dpi = 600,
width = 12.51,
height = 15.64 ,
units = "in"
)
Conclusion
In this tutorial, we have covered the steps to import, process, and visualize fiscal data in R.