Home > Blockchain >  Hide NAs, empty bars from bar-chart in ggplot
Hide NAs, empty bars from bar-chart in ggplot

Time:05-03

I have dataframe with 2 categorical variables and built bar chart via ggplot. The only problem is that Category: "Canada" and Category: "USA" have different categorical variables, that's why on the y-axis, as you see J,G in Canada and F,B in the USA are empty spaces.

Could you tell me how to avoid this issue? Also, I want to order bars in Canada and in USA descending by positive values

    library(tidyverse)
df <- data.frame (Origin = c("Canada", "Canada","Canada", "Canada","Canada", "Canada","USA","USA","USA","USA","USA","USA"),
                  Model = c("A","B","C","D","E","F","A","G","C","D","E","J"),
                  poschange = c(60, 45,34,56, 65, 44,40, 55, 35, 24,34,12),
                  negchange = c(-5,-2,-0.5,-2,-1,-0.05,-1,-3,-0.1,-3,-1.5,-0.9))

df2 <- df %>% pivot_longer(., cols=c('poschange','negchange'),
                           names_to = 'value_category') %>% 
  mutate(Groups = paste(Origin, Model),
         value_category = factor(value_category, levels = c("negchange", "poschange")))

my_color = c("A" = '#7fc97f', "B" = '#beaed4', "C" = '#fdc086', 
             "D" = '#ffff99', "E" = '#386cb0', "F" = '#f0027f', "white" = "white","G"="black","J"="blue")

ggplot(df2, aes(value, Model, 
                fill = ifelse(value_category == "negchange", "white", Model), 
                color = Model))   
  geom_col(position = "dodge")  
  scale_fill_manual(values = my_color, breaks = df2$Model)  
  scale_color_manual(values = my_color, breaks = df2$Model)  
  labs(fill = "Model")  
  facet_grid(Origin ~ ., switch = "y")  
  theme(axis.text.x = element_text(angle = 90),
        strip.background = element_rect(fill = "white"),
        strip.placement = "outside",
        strip.text.y.left = element_text(angle = 0),
        panel.spacing = unit(0, "lines"))

enter image description here

CodePudding user response:

To solve the empty bar issue, @Carl has given a feasible approach. To reorder the bars of positive and negative values, you need to set levels in factor (in this case, in the fill argument).

Also, remember the my_color vector should contain ALL colors for Model that you are going to plot.

library(tidyverse)
df <- data.frame (Origin = c("Canada", "Canada","Canada", "Canada","Canada", "Canada","USA","USA","USA","USA","USA","USA"),
                  Model = c("A","B","C","D","E","F","A","G","C","D","E","J"),
                  poschange = c(60, 45,34,56, 65, 44,40, 55, 35, 24,34,12),
                  negchange = c(-5,-2,-0.5,-2,-1,-0.05,-1,-3,-0.1,-3,-1.5,-0.9))

df2 <- df %>% pivot_longer(., cols=c('poschange','negchange'),
                           names_to = 'value_category') %>% 
  mutate(Groups = paste(Origin, Model))

my_color = c("A" = '#7fc97f', "B" = '#beaed4', "C" = '#fdc086', 
             "D" = '#ffff99', "E" = '#386cb0', "F" = '#f0027f', 
             "G" = "pink", "J" = "firebrick", "white" = "white")

ggplot(df2, aes(value, Model, 
                fill = factor(ifelse(value_category == "negchange", "white", Model), 
                              levels = c("white", unique(Model))), 
                color = Model))   
  geom_col(position = "dodge")  
  scale_fill_manual(values = my_color, breaks = df2$Model)  
  scale_color_manual(values = my_color, breaks = df2$Model)  
  labs(fill = "Model")  
  facet_grid(Origin ~ ., switch = "y", scale = "free_y")  
  theme(axis.text.x = element_text(angle = 90),
        strip.background = element_rect(fill = "white"),
        strip.placement = "outside",
        strip.text.y.left = element_text(angle = 0),
        panel.spacing = unit(0, "lines"))

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

CodePudding user response:

Add scales = "free_y and reorder_within:

library(tidyverse)
df <- data.frame (Origin = c("Canada", "Canada","Canada", "Canada","Canada", "Canada","USA","USA","USA","USA","USA","USA"),
                  Model = c("A","B","C","D","E","F","A","G","C","D","E","J"),
                  poschange = c(60, 45,34,56, 65, 44,40, 55, 35, 24,34,12),
                  negchange = c(-5,-2,-0.5,-2,-1,-0.05,-1,-3,-0.1,-3,-1.5,-0.9))

df2 <- df %>% pivot_longer(., cols=c('poschange','negchange'),
                           names_to = 'value_category') %>% 
  mutate(Groups = paste(Origin, Model),
         value_category = factor(value_category, levels = c("negchange", "poschange")),
         )

my_color = c("A" = '#7fc97f', "B" = '#beaed4', "C" = '#fdc086', 
             "D" = '#ffff99', "E" = '#386cb0', "F" = '#f0027f', "white" = "white","G"="black","J"="blue")

ggplot(df2, aes(value, tidytext::reorder_within(Model, value, Origin), 
                fill = ifelse(value_category == "negchange", "white", Model), 
                color = Model))   
  geom_col(position = "dodge")  
  scale_fill_manual(values = my_color, breaks = df2$Model)  
  scale_color_manual(values = my_color, breaks = df2$Model)  
  tidytext::scale_y_reordered()  
  labs(fill = "Model")  
  facet_grid(Origin ~ ., switch = "y", scales = "free_y")  
  theme(axis.text.x = element_text(angle = 90),
        strip.background = element_rect(fill = "white"),
        strip.placement = "outside",
        strip.text.y.left = element_text(angle = 0),
        panel.spacing = unit(0, "lines"))

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

  • Related