Home > front end >  R ggplot2 geom_bar y-axis sequence similar to respective column values sequence
R ggplot2 geom_bar y-axis sequence similar to respective column values sequence

Time:08-13

Based on the data and code below, I want to change the sequence of y-axis to be the same as in the Value column.

In the below screenshot it can be seen that 5-14 is in the middle of the plot and I want it to be after < 5 years just like in the data.

enter image description here

How can I do this?

Desired sequence:

Y-AXIS LABELS
85  
75 – 84
65 – 74
55 – 64
45 – 54
35 – 44
25 – 34
15 – 24
5 – 14
< 5 years

Data (pop_gen_df):

structure(list(age_group = c("<  5 years", "5 - 14", "15  -  24", 
"25  -  34", "35  -  44", "45  -  54", "55  -  64", "65  -  74", 
"75  -  84", "85  ", "<  5 years", "5 - 14", "15  -  24", "25  -  34", 
"35  -  44", "45  -  54", "55  -  64", "65  -  74", "75  -  84", 
"85  "), Type = c("males", "males", "males", "males", "males", 
"males", "males", "males", "males", "males", "females", "females", 
"females", "females", "females", "females", "females", "females", 
"females", "females"), Value = c(-6, -13, -13, -15, -17, -15, 
-11, -6, -3, -1, 6, 12, 12, 14, 16, 15, 12, 7, 4, 2)), row.names = c(NA, 
-20L), class = c("tbl_df", "tbl", "data.frame"))

Code:

library(tidyverse)
library(plotly)

# Plot
gg_pop_hisp = ggplot(pop_hisp_df, aes(x = age_group, y = Value, fill = Type))  
  geom_bar(data = subset(pop_hisp_df, Type == "females"), stat = "identity")   
  geom_bar(data = subset(pop_hisp_df, Type == "males"), stat = "identity")   
  scale_y_continuous(labels = function(z) paste0(abs(z), "%"))            # CHANGE
  scale_fill_manual(name = "Legend", values = c("females"="#FC921F", "males"="#149ECE"), labels = c("Females", "Males"))  
  ggtitle("HISPANIC POPULATION BY GENDER AND AGE GROUP")  
  labs(x = "PERCENTAGE POPULATION", y = "AGE GROUPS", fill = "Gender")  
  theme_minimal()  
  coord_flip()

# Interactive
ggplotly(gg_pop_hisp)

CodePudding user response:

forcats package to the rescue: to create a factor with the levels in the order in which they appear in data.frame. Which in this case works out nicely as they are nicely in order in your data.frame.

In the ggplot call: x = forcats::as_factor(age_group)

ggplot(pop_hisp_df, aes(x = forcats::as_factor(age_group), y = Value, fill = Type))  
  geom_bar(data = subset(pop_hisp_df, Type == "females"), stat = "identity")   
  geom_bar(data = subset(pop_hisp_df, Type == "males"), stat = "identity")   
  scale_y_continuous(labels = function(z) paste0(abs(z), "%"))            # CHANGE
  scale_fill_manual(name = "Legend", values = c("females"="#FC921F", "males"="#149ECE"), labels = c("Females", "Males"))  
  ggtitle("HISPANIC POPULATION BY GENDER AND AGE GROUP")  
  labs(x = "PERCENTAGE POPULATION", y = "AGE GROUPS", fill = "Gender")  
  theme_minimal()  
  coord_flip()

enter image description here

CodePudding user response:

You have to convert your age group variable to a factor with the order of the levels set in your desired order.

Besiedes forcats an option would be to use unique to set the order of the levels as the appear in your dataset.

library(plotly)

pop_hisp_df$age_group <- factor(pop_hisp_df$age_group, levels = unique(pop_hisp_df$age_group))

gg_pop_hisp = ggplot(pop_hisp_df, aes(x = age_group, y = Value, fill = Type))  
  geom_bar(data = subset(pop_hisp_df, Type == "females"), stat = "identity")   
  geom_bar(data = subset(pop_hisp_df, Type == "males"), stat = "identity")   
  scale_y_continuous(labels = function(z) paste0(abs(z), "%"))            # CHANGE
  scale_fill_manual(name = "Legend", values = c("females"="#FC921F", "males"="#149ECE"), labels = c("Females", "Males"))  
  ggtitle("HISPANIC POPULATION BY GENDER AND AGE GROUP")  
  labs(x = "PERCENTAGE POPULATION", y = "AGE GROUPS", fill = "Gender")  
  theme_minimal()  
  coord_flip()

# Interactive
ggplotly(gg_pop_hisp)

  • Related