1

I want to make a population pyramid chart to display differences of age and gender among different jobs in the DF i have (small sample below). I want to make the all the graphs automatically without having to change the code manually as it would be do time consuming for all jobs in my original DF. Making a pyramid chart in ggplot is hard but possible but i do not know how to automate it fully. I have two problems

  1. Currently i need to set expand limits manually. As in some jobs there are more men and in some more women. Even if i leave the length of the y-axis the same for all jobs (big and small), then i need to change the -/+ in expand_limits manually. Can i automate it somehow or give both expand limits -15000 and 15000 at the same time? Fright now i'm only manipulating one axis. (expand_limits(y=-15000).

  2. A Bonus but problem, that would be great if we could solve it but it's not a must. Is it possible to make y axis length and expand_limits dynamic so that it fits big and small jobs. For example:

Builders

expand_limits(y=-15000)+ 
  scale_y_continuous(breaks =c(-15000,-7500,0,7500,15000),
                      label =c(15000,7500,0,7500,15000))+

Civil servants

expand_limits(y=-500)+ 
  scale_y_continuous(breaks =c(-500,-250,0,250,500),
                      label =c(500,250,0,250,500))+

Any help is highly appreciated

Example DF

Job           Age     Gender     People
Builder       25-34    M          12752
Builder       25-34    F          386
Builder       35-44    M          13980
Builder       35-44    F          390
Builder       45-54    M          9686
Builder       45-54    F          361
Builder       55-64    M          4924
Builder       55-64    F          334
Builder       65+      M          961
Builder       65+      F          69
Builder       Under 25 M          4639
Builder       Under 25 F          200
Civil servant 25-34    M          88
Civil servant 25-34    F          274
Civil servant 35-44    M          58
Civil servant 35-44    F          464
Civil servant 45-54    M          45
Civil servant 45-54    F          523
Civil servant 55-64    M          43
Civil servant 55-64    F          234
Civil servant 65+      M          12
Civil servant 65+      F          121
Civil servant Under 25 M          21
Civil servant Under 25 F          76

My code

Pyramid <-Pyramid %>%
  filter(Job == "Builder") #"Civil servant" for other job in the example.

Pyramid$People <- ifelse(Pyramid$Gender == "M",Pyramid$People*-1, Pyramid$People)

Pyramid$Age <- fct_relevel(Pyramid$Age, "Under 25","25-34","35-44","45-54","55-64","65+")

ggplot(Pyramid ,aes(x=Age, y=People, fill=Gender))+
  geom_bar(data = subset(Pyramid, Gender =="F"), stat = "identity")+
  geom_bar(data = subset(Pyramid, Gender =="M"), stat = "identity")+
  coord_flip()+
  theme_minimal(base_size = 17)+
  scale_fill_manual(values = c("M" = "#0071ce",
                               "F" = "#d30031"),
                    name=" ",
                    labels=c("Men","Women"))+ 
  expand_limits(y=-15000)+  #This is the problem line for me
  scale_y_continuous(breaks =c(-15000,-7500,0,7500,15000), #And these two lines as well
                      label =c(15000,7500,0,7500,15000))+
  ylab(NULL)+
  theme(legend.position = "bottom",
        axis.title.y=element_blank())

This is what i would like, for different jobs the expand limits needs to be different +/- With expand_limits

This is with expand_limits removed without expand_limits

Expand_limits centers the genders

Picataro
  • 151
  • 6
  • could you maybe post the output of dput(Pyramid) instead? It's not easy to read in your data . – tjebo May 07 '22 at 11:41
  • and may I ask why you need to set expand_limits at all? Have you tried just deleting this line? – tjebo May 07 '22 at 11:42
  • @tjebo I added pictures with and without the expand_limits. Expand_limits is there to center the genders. and leave both sides the same mount of space to show the size difference better. – Picataro May 07 '22 at 11:47
  • I see. you could use something like `+coord_cartesian(ylim = c(-max(Pyramid$people), max(Pyramid$people))`. I personally don't really use expand_limits – tjebo May 07 '22 at 11:54
  • Also check https://stackoverflow.com/questions/4559229/drawing-pyramid-plot-using-r-and-ggplot2?noredirect=1&lq=1 for nicer pyramid plots – tjebo May 07 '22 at 11:54

1 Answers1

1

Try this:

library(tidyverse)

Pyramid <- tribble(
  ~Job, ~Age, ~Gender, ~People,
  "Builder", "25-34", "M", 12752,
  "Builder", "25-34", "F", 386,
  "Builder", "35-44", "M", 13980,
  "Builder", "35-44", "F", 390,
  "Builder", "45-54", "M", 9686,
  "Builder", "45-54", "F", 361,
  "Builder", "55-64", "M", 4924,
  "Builder", "55-64", "F", 334,
  "Builder", "65+", "M", 961,
  "Builder", "65+ ", "F", 69,
  "Builder", "Under 25", "M", 4639,
  "Builder", "Under 25", "F", 200,
  "Civil servant", "25-34", "M", 88,
  "Civil servant", "25-34", "F", 274,
  "Civil servant", "35-44", "M", 58,
  "Civil servant", "35-44", "F", 464,
  "Civil servant", "45-54", "M", 45,
  "Civil servant", "45-54", "F", 523,
  "Civil servant", "55-64", "M", 43,
  "Civil servant", "55-64", "F", 234,
  "Civil servant", "65+", "M", 12,
  "Civil servant", "65+", "F", 121,
  "Civil servant", "Under 25", "M", 21,
  "Civil servant", "Under 25", "F", 76
)

data_df <- Pyramid %>%
  filter(Job == "Builder") %>%
  mutate(
    People = if_else(Gender == "M", People * -1, People),
    Age = factor(Age, levels = c("Under 25", "25-34", "35-44", "45-54", "55-64", "65+"))
  ) 

max <- max(abs(data_df$People))
min <- max * -1

data_df %>%
  ggplot(aes(Age, People, fill = Gender)) +
  geom_col() +
  coord_flip() +
  theme_minimal(base_size = 17) +
  scale_fill_manual(values = c("#d30031", "#0071ce")) +
  scale_y_continuous(limits = c(min, max)) +
  labs(y = NULL, fill = NULL) +
  theme(legend.position = "bottom")

Created on 2022-05-07 by the reprex package (v2.0.1)

Carl
  • 4,232
  • 2
  • 12
  • 24
  • Is there a way how i can now turn the negative values on the axis positive? I mean instead of -15000, -10000 and - 5000 it would show 15000, 10000 and 5000? – Picataro May 13 '22 at 13:08
  • 1
    See if [this](https://stackoverflow.com/questions/38828250/how-to-change-negative-x-axis-breaks-labels-of-ggplot2-bar-graph-into-positive) helps. – Carl May 13 '22 at 13:19