Bookr Custom Functions

In addition to the custom iData functions, the bookr package has custom charting functions available. The package provides functions for line, bar, and scatter plots, consistently applying IMF branding, colors, and styles.

Pre-requisites

Ensure that you have the bookr package loaded, although it should have been loaded automatically following the setting up your computer instructions.

library(bookr)

IMF-Themed Charting Functions

The bookr package provides three primary functions for creating IMF-styled visualizations, line charts, bar charts, and scatter plots.

Line Charts

The plot_line_chart() function generates line charts with IMF-specific styles. You can utilize it by specifying the data, the x and y axis variables, and the title and subtitle of your chart.

Let’s explore an example below using GDP data for the U.S. from WDI.

# Load required libraries, including the WDI data
library(WDI)
library(dplyr)
library(bookr)
library(grid)

# Get real GDP data for the U.S. from the World Bank
us_gdp <- WDI(country = "US", indicator = "NY.GDP.MKTP.CD", start = 2000, end = 2023)

# Rescale GDP to trillions
us_gdp <- us_gdp %>%
  mutate(GDP_trillions = NY.GDP.MKTP.CD / 1e12)

# Plot using line chart function
plot_line_chart(
  us_gdp,
  "year",
  "GDP_trillions",
  plot_title = "U.S. Nominal GDP, 2000-2023",
  plot_subtitle = "(Trillions of Current USD)"
)

This line chart function:

✔️ Uses predefined IMF color schemes
✔️ Supports titles, subtitles, and captions
✔️ Ensures standardized axis formatting

Bar Charts

The plot_bar_chart() function creates stacked bar charts with predefined IMF color palettes.

Let’s explore an example using US GDP components.

# Load required libraries, including the WDI data
library(WDI)
library(dplyr)
library(tidyr)
library(bookr)
library(grid)
library(ggplot2)

# Define indicators
indicators <- c(
  GDP = "NY.GDP.MKTP.CD",
  Government = "NE.CON.GOVT.CD",
  Consumption = "NE.CON.PRVT.CD"
)

# Load real data
data_raw <- WDI(country = "US", indicator = indicators, start = 2018, end = 2023)

# Calculate investment: GDP - Consumption - Government
data_processed <- data_raw %>%
  mutate(
    across(c(GDP, Government, Consumption), ~ . / 1e12),
    Investment = GDP - Consumption - Government
  )

# Pivot to long format
data_long <- data_processed %>%
  pivot_longer(cols = c(Consumption, Government, Investment),
               names_to = "Component", values_to = "Value") %>%
  rename(year = year)

# GDP line data
gdp_line <- data_processed %>%
  transmute(year, GDP_trillions = GDP)

# Plot using custom bar chart function
plot_bar_chart(
  data_long,
  "year",
  "Value",
  fill_var = "Component",
  plot_title = "U.S. GDP Component Breakdown, 2018-2023",
  plot_subtitle = "(Trillions of USD)",
  plot_caption = NULL
) +
geom_line(data = gdp_line, aes(x = year, y = GDP_trillions), color = "black", size = 1) +
scale_x_continuous(breaks = 2018:2023) # ensure all years are labeled

This bar chart function:

✔️ Uses a predefined IMF bar color scheme
✔️ Supports grouping for stacked bars
✔️ Standardized axis styling

Scatter Plots

Similarly, the plot_scatter_chart() function generates scatter plots with regression lines. Let’s explore an example using 2022 data from LAC on inflation and interest rates.

library(WDI)
library(dplyr)
library(bookr)
library(grid)
library(ggplot2)
library(ggrepel)

# Define indicators
indicators <- c(
    Inflation = "FP.CPI.TOTL.ZG",
    Interest_rate = "FR.INR.LEND"
)

# Load 2022 data
macro_data <- WDI(
    country = "all",
    indicator = indicators,
    start = 2022,
    end = 2022,
    extra = TRUE
)

# Filter and clean for LAC
lac_data <- macro_data %>%
    filter(
        region == "Latin America & Caribbean",
        !is.na(Inflation),
        !is.na(Interest_rate)
    ) %>%
    mutate(category = iso3c)

# Generate base chart
p <- plot_scatter_chart(
    lac_data,
    "Inflation",
    "Interest_rate",
    plot_title = "LAC Inflation vs. Interest Rate, 2022",
    plot_subtitle = "(Percent)",
    x_label = "Inflation Rate (%)",
    y_label = "Interest Rate (%)",
        point_size = 2.5,
    point_shape = 21,
    reg_line = TRUE
)

# Add ISO3 labels (must specify x and y again)
p + geom_text_repel(
    aes(x = Inflation, y = Interest_rate, label = iso3c),
    size = 3,
    max.overlaps = 25,
    box.padding = 0.25,
    min.segment.length = 0,
    segment.color = "grey50"
)

This scatter plot function:

✔️ Adds regression lines automatically
✔️ Supports title and axis customization

Dual Axis Plots

The plot_dual_axis() function allows you to display two indicators on the same time axis using dual y-axes. This is useful when comparing variables that differ in scale but are conceptually related.

In the example below, we use WDI data to plot Brazil’s real GDP growth on the left y-axis and the CPI on the right y-axis from 2000-2024.

# WDI indicators: GDP growth and CPI inflation
df_dual <- WDI(
    country = "BR", 
    indicator = c("NY.GDP.MKTP.KD.ZG", "FP.CPI.TOTL.ZG"),
    start = 2000, end = 2024
) |>
    rename(
        gdp_growth = NY.GDP.MKTP.KD.ZG,
        inflation = FP.CPI.TOTL.ZG,
        date = year
    ) |>
    dplyr::filter(!is.na(gdp_growth) & !is.na(inflation))

# Plot
plot_dual_axis(
    data = df_dual,
    var_left = gdp_growth,
    var_right = inflation,
    plot_title = "Brazil: GDP Growth and Inflation",
    y_left_lbl = "GDP Growth (Percent)",
    y_right_lbl = "Inflation (Percent)",
    plot_subtitle = "2000–2022"
)

This dual axis function:

✔️ Supports simultaneous plotting of two indicators with different units
✔️ Applies standardized IMF styling, including fonts and color mapping
✔️ Automatically rescales the secondary axis for accurate alignment and interpretation

IMF Branding & Custom Themes

In addition to some predefined charting functions, the package provides IMF-specific colors and themes:

  • theme_imf(): Applies standard IMF-styled charts.

  • theme_imf_panel(): Applies IMF panel chart theme and layouts.

You also have the ability to apply these themes manually to any ggplot styled chart. Let’s explore how to do that with an example using Argentina GDP data.

library(WDI)
library(dplyr)
library(ggplot2)
library(bookr)
library(grid)

# Load Argentina GDP data for 5 years
arg_data <- WDI(country = "AR", indicator = "NY.GDP.MKTP.CD", start = 2018, end = 2022)

# Prepare data with constant fill group
arg_gdp <- arg_data %>%
  arrange(year) %>%
  mutate(
    GDP_trillions = NY.GDP.MKTP.CD / 1e12,
    fill_group = "Argentina"  # constant category to get single-color bars
  )

# Plot with consistent IMF color, no fill variation
ggplot(arg_gdp, aes(x = factor(year), y = GDP_trillions, fill = fill_group)) +
  geom_bar(stat = "identity") +
  labs(
    title = "Argentina GDP, 2018–2022",
    subtitle = "(Trillions of current USD)",
    x = NULL,
    y = "GDP (Trillions USD)"
  ) +
  theme_imf() +
  scale_imf_colors() +
  guides(fill = "none")

This theme:

✔️ Ensures consistent fonts (Segoe UI)
✔️ Controls gridline visibility, axis formatting, and legend placement

We can also utilize the theme to create panel charts of varying sizes.

Let’s, for example, use the publicly available COVID-19 data to create an IMF themed panel.

# Load required libraries
library(ggplot2)
library(dplyr)
library(readxl)
library(here)
library(patchwork)
library(scales) 

# Load COVID dataset
covid_data <- read_excel(here("databases/owid-covid-data.xlsx"), sheet = "Sheet1") %>%
  mutate(date = as.Date(date))

# Filter for selected countries and dates
covid_filtered <- covid_data %>%
  filter(location %in% c("United States", "India", "Brazil"), date >= as.Date("2021-01-01"))  

# Create a chart on cumulative Covid-19 deaths
p1 <- covid_filtered %>%
  filter(!is.na(total_deaths)) %>%
  ggplot(aes(x = date, y = total_deaths, color = location, group = location)) +
  geom_line(size = 1.2) +
  labs(title = "Cumulative COVID-19 Deaths",
       subtitle = "Selected countries, 2021 onward",
       x = "Date", y = NULL) +
  scale_x_date(date_breaks = "9 months", date_labels = "%b %Y") +
  theme_imf_panel() +
  scale_imf_colors() +
  theme(
    legend.position = "bottom",
    legend.title = element_blank(),
    axis.text.x = element_text(angle = 0, hjust = 0.5)  # horizontal labels
  )

# Create a bar chart on total Covid-19 cases
p2 <- covid_filtered %>%
  group_by(location) %>%
  summarise(total_cases = sum(new_cases, na.rm = TRUE)) %>%
  ggplot(aes(x = location, y = total_cases, fill = location)) +
  geom_bar(stat = "identity") +
  labs(title = "Total COVID-19 Cases in 2021",
       subtitle = "Cumulative sum by country",
       x = "", y = NULL) +  # Remove y-axis label
  theme_imf_panel() +
  scale_imf_colors() +
  theme(legend.position = "bottom",
        legend.title = element_blank())  # Remove legend title

# Combine both plots into a panel
combined_plot <- (p1 | p2) +
  plot_annotation(
    title = "Select COVID-19 Metrics",
    subtitle = "Cumulative deaths and total cases for Brazil, India and USA"
  ) &
  theme(
    plot.title = element_text(hjust = 0.5),
    plot.subtitle = element_text(hjust = 0.5)
  )

combined_plot

Saving Charts

The save_plot() function allows saving plots in IMF-standard formats and dimensions in the current directory you are working in. Let’s save a chart (p1) from our previous example as a single chart type.

save_plot(p1, "test_save_imf_theme.png")

This function:

✔️ Saves images in predefined sizes
✔️ Supports high-resolution exports for reports

The functions within the bookr package simplify creating simple IMF-branded charts with consistent styling and formatting.

Unlike single charts, panel charts vary in size depending on the number of subplots. The save_plot() function does not automatically set a fixed size for panels, so you should specify dimensions when saving, for example for a half-page panel, a good width and height would be 9 and 5.

ggsave_imf(combined_plot, "test_panel_chart.png", width = 9, height = 5)

These are the custom charting related functions available in the bookr package and how to use them.