Data Source:

https://www.kaggle.com/datasets/lsind18/who-immunization-coverage The WHO Dataset is not very usable though so I cleaned and manipulated it quite a bit to allow for the type of visualisation I want. You can download my cleaned version of the BCG coverage file here: https://drive.google.com/drive/folders/1CQ_ETiCU_cvbdQO6zEIWdzDGY3r-n0v1?usp=sharing

Loading Packages and Dataset

library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.2     ✔ readr     2.1.4
## ✔ forcats   1.0.0     ✔ stringr   1.5.0
## ✔ ggplot2   3.4.2     ✔ tibble    3.2.1
## ✔ lubridate 1.9.2     ✔ tidyr     1.3.0
## ✔ purrr     1.0.1     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(scales)
## 
## Attaching package: 'scales'
## 
## The following object is masked from 'package:purrr':
## 
##     discard
## 
## The following object is masked from 'package:readr':
## 
##     col_factor
library(RColorBrewer)
library(extrafont)
## Registering fonts with R
BCG <- read.csv("BCG.csv")

Setting theme

theme_set(theme_classic()+
            theme(
              plot.title = element_text(hjust = 0.5, 
                                        family = "Corbel",
                                        size = 20,
                                        face = "bold"
                                        ),
              plot.subtitle = element_text(hjust = 0.5,
                                           family = "Corbel",
                                           size = 16,
                                           face = "bold"),
              plot.caption = element_text(family = "Corbel",
                                          size = 8,
                                          face = "bold"),
              axis.title.x = element_text(color = "black",
                                          family = "Corbel",
                                          size = 12,
                                          face = "bold"),
              axis.title.y = element_text(color = "black",
                                          family = "Corbel",
                                          size = 12,
                                          face = "bold")
              )
          )

Average Immunisation rates across Continents in 2021.

BCG %>% 
  filter(Year == 2021) %>% 
  ggplot(aes(x = Continent, y = Coverage, fill = Continent))+
  stat_summary(
    geom = "bar",
    fun = "mean",
    colour = "black",
    width = 0.7,
    alpha = 0.7
  )+
  stat_summary(
    geom = "errorbar",
    fun = "mean",
    fun.min = "min",
    fun.max = "max",
    width = 0.4,
    linewidth = 0.8
  )+
  scale_x_discrete()+
  scale_y_continuous(name = "Coverage",
                     limits = c(0, 110),
                     breaks = seq(0, 100, 10),
                     labels = label_percent(scale = 1),
                     expand = expansion(0))+
  labs( title = str_wrap("Average Under-one BCG immunisation rates in 2021",
                         40),
        subtitle = "Errorbars indicate range between minimum and 
        maximum values for each continent.",
        caption = "Source: WHO Immunization Coverage")+
  scale_fill_brewer(palette = "Spectral")+
  theme(legend.position = "none")
## Warning: Removed 7 rows containing non-finite values (`stat_summary()`).
## Removed 7 rows containing non-finite values (`stat_summary()`).

Average coverage per continent shown in five year periods

BCG %>% 
  filter(Year %in% c(2000, 2005, 2010, 2015, 2020)) %>%
  mutate(Year = as.factor(Year)) %>% 
  ggplot(aes(x = Continent, y = Coverage, fill = Year))+
  stat_summary(
    geom = "bar",
    fun = "mean",
    colour = "black",
    position = position_dodge2(),
    alpha = 0.7,
    width = 0.8
  )+
  scale_y_continuous(name = "Coverage",
                     limits = c(0, 110),
                     breaks = seq(0, 100, 10),
                     labels = label_percent(scale = 1),
                     expand = expansion(0))+
  labs( title = str_wrap("Average Under-one BCG immunisation rates 
                         in five-year periods",
                         40),
        subtitle = "Rates in Africa and Oceania remained below 90% 
        over a 20-year period",
        caption = "Source: WHO Immunization Coverage")+
  scale_fill_brewer(palette = "Set1")+
  theme(legend.position = "bottom")
## Warning: Removed 29 rows containing non-finite values (`stat_summary()`).

Comparison of Coverage rates between Nigeria, South Africa and Ghana

BCG %>% 
  filter(Country %in% c("Nigeria", "South Africa", "Ghana")) %>% 
  ggplot(aes(x = Year, y = Coverage, colour = Country))+
  geom_point()+
  geom_line()+
  scale_x_continuous(name = "Year",
                     limits = c(2000, 2026),
                     breaks = seq(2000, 2025, 5))+
  scale_y_continuous(name = "Coverage",
                     limits = c(0, 110),
                     breaks = seq(0, 100, 10),
                     labels = label_percent(scale = 1),
                     expand = expansion(0))+
  labs( title = "Under-one BCG immunisation rates from 2000 to 2021",
        caption = "Source: WHO Immunization Coverage")+
  annotate(
    geom = "text",
    label = str_wrap("Despite remarkable progress, Nigeria still
    records lower coverage than Ghana and South Africa", 25),
    x = 2015,
    y = 35,
    size = 3
  )+
  annotate(
    geom = "text",
    label = "Nigeria",
    x = 2023,
    y = 74,
    colour = "steelblue"
  )+
  annotate(
    geom = "text",
    label = "South Africa",
    x = 2024,
    y = 86,
    colour = "steelblue"
  )+
  annotate(
    geom = "text",
    label = "Ghana",
    x = 2023,
    y = 100,
    colour = "steelblue"
  )+
  theme(legend.position = "none")+
  scale_colour_brewer(palette = "Dark2")