The graphic highlights the dramatic global decline in fertility rates from the 1950s to the 2010s, with significant reductions driven by middle-income countries like India and China. It also shows that the poorest and war-torn nations, primarily in Africa, continue to have high fertility rates.
A4 Size Viz
Our World in Data
Public Health
Author
Aditya Dahiya
Published
July 12, 2024
Source of the Data: The fertility rate data is sourced from the United Nations’ World Population Prospects (2022) and has been processed and presented by Our World in Data. The dataset provides the average number of live births a hypothetical cohort of women would have at the end of their reproductive period, assuming they experienced the fertility rates of a specific period throughout their lives without mortality impact. The data covers the period from 1950 to 2021 and is measured in live births per woman. For more information, visit the UN’s World Population Prospects page here and here.
Total Fertility Rate (TFR) The Total Fertility Rate (TFR) is the average number of children a woman is expected to have in her lifetime based on current birth rates. It’s a measure used to understand how many children are born in a population.
How I made these graphics?
Getting the data
Code
# Data Import and Wrangling Toolslibrary(tidyverse) # All things tidylibrary(owidR) # Get data from Our World in R# Final plot toolslibrary(scales) # Nice Scales for ggplot2library(fontawesome) # Icons display in ggplot2library(ggtext) # Markdown text supportlibrary(showtext) # Display fonts in ggplot2library(colorspace) # To lighten and darken colourslibrary(patchwork) # Combining plotssearch1 <- owidR::owid_search("fertility")df1 <-owid("children-per-woman")popdf <-owid("population-with-un-projections")
Visualization Parameters
Code
# Font for titlesfont_add_google("Chakra Petch",family ="title_font") # Font for the captionfont_add_google("Saira Semi Condensed",family ="caption_font") # Font for plot textfont_add_google("Changa",family ="body_font") showtext_auto()# Colour Palettemypal <-rev(paletteer::paletteer_d("LaCroixColoR::Lime")[c(1,2,4:6)])# Background Colourbg_col <-"grey98"text_col <-"grey10"text_hil <-"grey25"# Base Text Sizebts <-80plot_title <-"Global Fertility Drop (1950-2021)"plot_subtitle <-"The global Total Fertility Rate (TFR) has dropped from 5 (1950s) to 2.1 (2021), driven primarily by declines in middle-income countries, like China and India. Poor and war-torn nations, particularly in Africa, maintain high fertility rates. Wealthy European countries have seen minimal declines but have gone below replacement levels."data_annotation <-"About the Data: This data on fertility rates, sourced from the United Nations' World Population Prospects (2022) and processed by Our World in Data, spans from 1950 to 2021. It reflects the average number of live births per woman, with age-specific rates, providing insights into global fertility trends across decades."# Caption stuff for the plotsysfonts::font_add(family ="Font Awesome 6 Brands",regular = here::here("docs", "Font Awesome 6 Brands-Regular-400.otf"))github <-""github_username <-"aditya-dahiya"xtwitter <-""xtwitter_username <-"@adityadahiyaias"social_caption_1 <- glue::glue("<span style='font-family:\"Font Awesome 6 Brands\";'>{github};</span> <span style='color: {text_hil}'>{github_username} </span>")social_caption_2 <- glue::glue("<span style='font-family:\"Font Awesome 6 Brands\";'>{xtwitter};</span> <span style='color: {text_hil}'>{xtwitter_username}</span>")plot_caption <-paste0("**Data:** United Nations & Our World in Data | ","**Code:** ", social_caption_1, " | **Graphics:** ", social_caption_2 )rm(github, github_username, xtwitter, xtwitter_username, social_caption_1, social_caption_2)
Data Wrangling
Code
# A tibble for the fertility levels in each decadedf2 <- df1 |>as_tibble() |> janitor::clean_names() |>rename(fertility = fertility_rate_sex_all_age_all_variant_estimates) |>filter(!is.na(code)) |>filter(entity !="World") |>select(-countries_continents) |>filter(!str_detect(code, "OWID"))# A tibble of populations for each coutnry in each decadepopdf1 <- popdf |>as_tibble() |> janitor::clean_names() |>filter(!is.na(code)) |>filter(entity !="World") |>mutate(population =ifelse(is.na(population_sex_all_age_all_variant_estimates), population_sex_all_age_all_variant_medium, population_sex_all_age_all_variant_estimates ) ) |>select(-c(population_sex_all_age_all_variant_estimates, population_sex_all_age_all_variant_medium))df_continents <- rnaturalearth::ne_countries() |>as_tibble() |> janitor::clean_names() |>select(iso_a3, continent) |>rename(code = iso_a3)levels_x <-c("1950s", "1960s", "1970s", "1980s", "1990s", "2000s", "2010s", "2021")# A tibble to use for final plottingdf3 <- df2 |>left_join(popdf1) |>left_join(df_continents) |>drop_na() |>filter(year >=1951& year <=2020) |>mutate(year =cut( year, breaks =seq(1950, 2020, 10), labels =paste0(seq(1950, 2010, 10), "s") ) ) |>group_by(continent, entity, code, year) |>summarise(fertility =weighted.mean(fertility, w = population, na.rm = T),population =mean(population, na.rm = T) ) |>bind_rows( df2 |>left_join(popdf1) |>left_join(df_continents) |>drop_na() |>filter(year ==2021) |>mutate(year =as.character(year)) ) |>mutate(year =fct(year, levels = levels_x))# A tibble to use for global averagesdf4 <- df2 |>left_join(popdf1) |>drop_na() |>filter(year >=1951& year <=2020) |>mutate(year =cut( year, breaks =seq(1950, 2020, 10), labels =paste0(seq(1950, 2010, 10), "s") ) ) |>group_by(year) |>summarise(fertility =weighted.mean(fertility, w = population, na.rm = T) ) |>bind_rows( df2 |>left_join(popdf1) |>drop_na() |>filter(year ==2021) |>group_by(year) |>summarise(fertility =weighted.mean(fertility, w = population, na.rm = T) ) |>mutate(year =as.character(year)) ) |>mutate(year =fct(year, levels = levels_x))