Population Pyramids with 'ggplot2'

Build population pyramids, the back-to-back bar charts of a population by age group and sex, as layers of a 'ggplot2' plot. A position adjustment mirrors one side and stacks subgroups within each side, so bars, labels and lines from any layer land on the correct side while the plot can still be faceted, themed and extended as usual. A coordinate system labels both sides with absolute values, gives them one shared scale, and places the age axis on either side or in a gap at the centre. Further layers count individual records or sum aggregated values, show proportions, label the bars, and draw a second population as a stepped outline for comparison.


ggpyramid

Lifecycle:experimental R-CMD-check

ggpyramid is a ggplot2 extension for building population pyramids: back-to-back bar charts of a population by age group and sex. A pyramid is one more layer in an ordinary ggplot, so scales, facets, themes and further layers work as they do anywhere else in ggplot2.

Installation

Install the released version of ggpyramid from CRAN with:

install.packages("ggpyramid")

Or the development version from GitHub with:

# install.packages("pak")
pak::pak("matanhakim/ggpyramid")

Example

geom_pyramid() draws the bars and coord_pyramid() the axes. The bars sum a value when one is mapped, as here, and count rows when it is not, so they accept aggregated tables and individual records alike. europe_pop holds the population of four European countries in 2004 and 2024, from Eurostat.

library(ggplot2)
library(ggpyramid)

france <- subset(europe_pop, country == "France" & year == 2024)

ggplot(france, aes(x = population, y = age, fill = sex)) +
  geom_pyramid(width = 1, colour = "white") +
  scale_x_continuous(labels = scales::label_comma()) +
  coord_pyramid(age_axis = "centre") +
  labs(x = NULL, y = NULL, fill = NULL) +
  theme_pyramid()

denominator turns the bars into shares of the panel or of each side, and each facet gets its own denominator. geom_pyramid_outline() draws a second population as a stepped line over the bars:

ggplot(europe_pop, aes(x = population, y = age, fill = sex)) +
  geom_pyramid(data = ~ subset(.x, year == 2024), denominator = "total") +
  geom_pyramid_outline(data = ~ subset(.x, year == 2004), denominator = "total") +
  scale_x_continuous(labels = scales::label_percent()) +
  coord_pyramid() +
  facet_wrap(vars(country)) +
  labs(
    x = NULL,
    y = NULL,
    fill = "2024",
    caption = "Share of the population. The outline shows 2004."
  ) +
  theme_pyramid()

geom_pyramid_text() labels each bar at its end, on both sides:

ireland <- subset(europe_pop, country == "Ireland" & year == 2024)

ggplot(ireland, aes(x = population, y = age, fill = sex)) +
  geom_pyramid(denominator = "side") +
  geom_pyramid_text(
    denominator = "side",
    labels = scales::label_percent(accuracy = 0.1),
    size = 2.6
  ) +
  scale_x_continuous(
    labels = scales::label_percent(),
    expand = expansion(mult = 0.15)
  ) +
  coord_pyramid(age_axis = "centre") +
  labs(x = "Share of each sex", y = NULL, fill = NULL) +
  theme_pyramid()

vignette("ggpyramid") covers the rest: placing the age axis, subgroups within each side, vertical pyramids, and how the two sides are drawn.

Related work

apyramid builds a complete pyramid from one function call. geom_pyramid() in ggstats is a layer that mirrors bars by their position in a stack. ggpyramid takes the side from a variable and adds the coordinate system, labels and outlines that a pyramid needs, each as a separate ggplot2 component.

Reference manual

It appears you don't have a PDF plugin for this browser. You can click here to download the reference manual.

install.packages("ggpyramid")

0.1.0 by Matan Hakim, 15 hours ago


https://github.com/matanhakim/ggpyramid, https://matanhakim.github.io/ggpyramid/


Report a bug at https://github.com/matanhakim/ggpyramid/issues


Browse source code at https://github.com/cran/ggpyramid


Authors: Matan Hakim [aut, cre, cph] (ORCID:


Documentation:   PDF Manual  


MIT + file LICENSE license


Imports cli, ggplot2, rlang, scales, stats, utils, vctrs

Suggests knitr, rmarkdown, testthat, vdiffr


See at CRAN