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
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).
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 /-
This is with expand_limits removed
Expand_limits centers the genders
CodePudding user response:
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)