Home > Back-end >  How to make expand_limits dynamic in a pyramid chart?
How to make expand_limits dynamic in a pyramid chart?

Time:05-13

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

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)

  • Related