Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Overlay two population pyramid plots in one ggplot graph

I’m trying to overlay two population pyramid plots in one ggplot2 plot. I first created a plot using the census data with lighter colors and then try to superimpose another plot (created using the survey data with darker colors, say darkred, steelblue) onto the former. Is there any way I can do that while having their gender (sex) labels displayed on the legend? (Male (c/s) refers to Male (census/survey), the same goes to Female). This post is a reference.

library(tidyverse)
library(ggplot2)

# create data
census <- data.frame(age = c("20-29", "30-39", "40-49", "50-59", "60-69", "70+"), PopPerc = c(12.45, 14.14, 16.56, 14.73, 13.77, 11.00, -11.18, -13.13, -16.67, -15.10, -14.60, -13.82), sex = c("Male (c)", "Male (c)", "Male (c)", "Male (c)", "Male (c)", "Male (c)", "Female (c)", "Female (c)", "Female (c)", "Female (c)", "Female (c)", "Female (c)"), signal = c(1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1))

survey <- data.frame(age = c("20-29", "30-39", "40-49", "50-59", "60-69", "70+"), PopPerc = c(12.18, 24.70, 27.54, 19.22, 11.77, 4.60, -11.94, -25.76, -29.59, -18.11, -10.84, -3.76), sex = c("Male (s)", "Male (s)", "Male (s)", "Male (s)", "Male (s)", "Male (s)", "Female (s)", "Female (s)", "Female (s)", "Female (s)", "Female (s)", "Female (s)"), signal = c(1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1))

# create base plot using census data

base <- census %>%
  ggplot() + # build the plot with ggplot2
  geom_bar(aes(x = age, y = PopPerc, fill = sex), stat = 'identity') + 
  geom_text(aes(
    # create the text
    x = age,
    y = PopPerc + signal * .3,
    label = abs(PopPerc)
  )) +
  coord_flip() + # flip the plot
  scale_fill_manual(name = '', values = alpha(c('lightpink', 'lightblue1'), alpha = 0.5)) + (darkred = female, steelblue = male)
  scale_y_continuous(
    # scale the y-lab
    labels = function(x) {
      paste(abs(x), '%')
    }
  ) +
  labs(
    # name the labs
    x = '',
    y = 'Participants by %',
    title = ''
  ) +
  theme(
    # costume the theme
    axis.text.x = element_text(vjust = .5),
    panel.grid.major.y = element_line(color = 'lightgray', linetype =
                                        'dashed'),
    legend.position = 'top',
    legend.justification = 'center'
  ) +
  theme_classic() 

base

>Solution :

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

I’m not a 100% clear on what you want, but I think this should get you started at least. I bind the two data.frames together, like so:

bind_rows(census, survey, .id = 'type') %>%
  ggplot() + 
  geom_col(aes(PopPerc, age, fill = sex), position = 'identity', alpha = 0.5) + 
  geom_text(aes(PopPerc + signal * 1, age, label = abs(PopPerc))) +
  scale_fill_manual(values = c('lightpink', 'darkred', 'lightblue1', 'steelblue')) + 
  scale_x_continuous(labels = \(x) paste(abs(x), '%')) +
  labs(
    # name the labs
    x = 'Participants by %',
    y = NULL, fill = NULL
  ) +
  theme(
    # customize the theme
    axis.text.x = element_text(vjust = .5),
    panel.grid.major.y = element_line(color = 'lightgray', linetype = 'dashed'),
    legend.position = 'top',
    legend.justification = 'center'
  ) +
  theme_classic() 

enter image description here

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading