How can we arrange the bars for each facets_grid in ggplot ?

It seems ggplot bars are not responding to reorder or even arrange
Probably, is this impossible within facet ?

  viz <- data.frame(type = c(rep("A",5),rep("B",4)),
                    project = c("ABC","BCD","CDE","EFG","FGI","GIK","IKL","KLM","LMO"),
                    complexity = c(.8,.95,.6,.8,.9,.3,.7,.2,.6),
                    impact = c(1,.8,.7,.8,.9,.4,.8,.6,.5),
                    relevance = c(.8,.5,.7,.9,.1,.8,.7,.7,.8),
                    stringsAsFactors = F)
  
  viz_lng <- viz %>% 
    gather(-c(1,2), key = category, value = importance)%>% 
    arrange(desc(importance))
  
  ggplot(viz_lng[which(viz_lng$importance>0),], 
         aes(x = project, y= importance, group = project, fill = project)) +
    geom_bar(stat="identity") + 
    facet_grid(vars(category), vars(type), scales="free_x")  +
    guides(fill=FALSE) + theme_bw() +
    theme(strip.text = element_text(size = 14),
          axis.text.x = element_text(angle = 45, hjust = 1),
          legend.title = element_blank(),
          axis.text = element_text(size = 14),
          axis.title = element_text(size = 14)) 

## reorder
  ggplot(viz_lng[which(viz_lng$importance>0),], 
         aes(x = reorder(project, importance), y= importance, group = project, fill = project)) +
    geom_bar(stat="identity") + 
    facet_grid(vars(category), vars(type), scales="free_x")  +
    guides(fill=FALSE) + theme_bw() +
    theme(strip.text = element_text(size = 14),
          axis.text.x = element_text(angle = 45, hjust = 1),
          legend.title = element_blank(),
          axis.text = element_text(size = 14),
          axis.title = element_text(size = 14)) 

As I understand it running your code, it is actually reordering it correctly. You're currently ordering by the mean value (the default value for the reorder function). Perhaps you wish to order it by the total sum of importance of each project? Is that it?

## reorder
ggplot(viz_lng[which(viz_lng$importance>0),], 
       aes(x = reorder(project, importance, FUN = sum), y= importance, group = project, fill = project)) +
  geom_bar(stat="identity") + 
  facet_grid(vars(category), vars(type), scales="free_x")  +
  guides(fill=FALSE) + theme_bw() +
  theme(strip.text = element_text(size = 14),
        axis.text.x = element_text(angle = 45, hjust = 1),
        legend.title = element_blank(),
        axis.text = element_text(size = 14),
        axis.title = element_text(size = 14)) 

temp

If you want it reordered from left to right on the plot, you can always make the function call:

reorder(project, -importance, FUN = sum)
2 Likes

Thanks for response.

Might be my explanation was incorrect.
Can we arrange the bars for each grid

Let's share an example.
In the above graph,

grid(A, Relevance)
current order:
FGI > CDE > BCD > EFG > ABC

Expected:
FGI > BCD > CDE > ABC > EFG

Similarly in
grid( B, complexity)
Expected:
KLM > GIK > LMO > IKL

1 Like

Is this what you're after? Check out David Robinson's function here https://github.com/dgrtwo/drlib/blob/master/R/reorder_within.R

As far as i know you have to use facet_wrap to use this function (not facet_grid).
Just re-arranged the columns and rows so that the plot comes closer to a grid.

library(tidyverse)

library(drlib)
viz <- data.frame(type = c(rep("A",5),rep("B",4)),
                  project = c("ABC","BCD","CDE","EFG","FGI","GIK","IKL","KLM","LMO"),
                  complexity = c(.8,.95,.6,.8,.9,.3,.7,.2,.6),
                  impact = c(1,.8,.7,.8,.9,.4,.8,.6,.5),
                  relevance = c(.8,.5,.7,.9,.1,.8,.7,.7,.8),
                  stringsAsFactors = F)

viz_lng <- viz %>% 
  gather(-c(1,2), key = category, value = importance)%>% 
  arrange(desc(importance))

ggplot(viz_lng[which(viz_lng$importance>0),], 
       aes(x = reorder_within(project, importance, category, ), 
           y= importance, group = project, fill = project)) +
  geom_bar(stat="identity") + 
  scale_x_reordered() +
  facet_wrap(vars(category, type), scales="free_x", ncol=2)  +
  guides(fill=FALSE) + theme_bw() +
  theme(strip.text = element_text(size = 14),
        axis.text.x = element_text(angle = 45, hjust = 1),
        legend.title = element_blank(),
        axis.text = element_text(size = 14),
        axis.title = element_text(size = 14)) 

Created on 2019-05-23 by the reprex package (v0.3.0)

3 Likes

thanks for quick help. I could not install drlib package in a normal way.
Also, looked into David github but couldnt find source to install.

Also, could be this also be done in facet_grid as well ?

devtools::install_github("dgrtwo/drlib") gets you the package.
Should work with facet_grid as well, but I am not sure.

1 Like

Thanks and I accept your solution.

Is there way to eliminate the empty bars in each grid ?
by naming x axis in each grid x axis ?
But not using wrap ?

library(tidyverse)

library(drlib)
viz <- data.frame(type = c(rep("A",5),rep("B",4)),
                  project = c("ABC","BCD","CDE","EFG","FGI","GIK","IKL","KLM","LMO"),
                  complexity = c(.8,.95,.6,.8,.9,.3,.7,.2,.6),
                  impact = c(1,.8,.7,.8,.9,.4,.8,.6,.5),
                  relevance = c(.8,.5,.7,.9,.1,.8,.7,.7,.8),
                  stringsAsFactors = F)

viz_lng <- viz %>% 
    gather(-c(1,2), key = category, value = importance)%>% 
    arrange(desc(importance))

ggplot(viz_lng[which(viz_lng$importance>0),], 
       aes(x = reorder_within(project, importance, category, ), 
           y= importance, group = project, fill = project)) +
    geom_bar(stat="identity") + 
    scale_x_reordered() +
    facet_grid(vars(category), vars(type), scales="free_x")  +
    guides(fill=FALSE) + theme_bw() +
    theme(strip.text = element_text(size = 14),
          axis.text.x = element_text(angle = 45, hjust = 1),
          legend.title = element_blank(),
          axis.text = element_text(size = 14),
          axis.title = element_text(size = 14))

Your solution works as long as data is in integer form.

Why does this code breaks when used percentage values ?

library(tidyverse)

library(drlib)
viz <- data.frame(type = c(rep("A",5),rep("B",4)),
                  project = c("ABC","BCD","CDE","EFG","FGI","GIK","IKL","KLM","LMO"),
                  complexity = c(.8,.95,.6,.8,.9,.3,.7,.2,.6),
                  impact = c(1,.8,.7,.8,.9,.4,.8,.6,.5),
                  relevance = c(.8,.5,.7,.9,.1,.8,.7,.7,.8),
                  stringsAsFactors = F)

## Convert to percentage
viz[,3:5] <- map(viz[,3:5], scales::percent) 

viz_lng <- viz %>% 
  gather(-c(1,2), key = category, value = importance)%>% 
  arrange(desc(importance))

ggplot(viz_lng[which(viz_lng$importance>0),], 
       aes(x = reorder_within(project, importance, category, ), 
           y= importance, group = project, fill = project)) +
  geom_bar(stat="identity") + 
  scale_x_reordered() +
  facet_wrap(vars(category, type), scales="free_x", ncol=2)  +
  guides(fill=FALSE) + theme_bw() +
  theme(strip.text = element_text(size = 14),
        axis.text.x = element_text(angle = 45, hjust = 1),
        legend.title = element_blank(),
        axis.text = element_text(size = 14),
        axis.title = element_text(size = 14)) 

This doesn't work because there is no percentage class, you are converting your numeric variable into text so they can't be used as numeric values any more.

1 Like

Your viz[,3:5] <- map(viz[,3:5], scales::percent) makes the values to a character class, but it needs to be numeric. There is no need to convert it to percent in advance; just use the scales function in

scale_y_continuous(labels=scales::percent)

. See below

library(tidyverse)
#> Registered S3 methods overwritten by 'ggplot2':
#>   method         from 
#>   [.quosures     rlang
#>   c.quosures     rlang
#>   print.quosures rlang

devtools::install_github("dgrtwo/drlib")
#> Skipping install of 'drlib' from a github remote, the SHA1 (2be33ab6) has not changed since last install.
#>   Use `force = TRUE` to force installation

library(drlib)

viz <- data.frame(type = c(rep("A",5),rep("B",4)),
                  
                  project = c("ABC","BCD","CDE","EFG","FGI","GIK","IKL","KLM","LMO"),
                  
                  complexity = c(.8,.95,.6,.8,.9,.3,.7,.2,.6),
                  
                  impact = c(1,.8,.7,.8,.9,.4,.8,.6,.5),
                  
                  relevance = c(.8,.5,.7,.9,.1,.8,.7,.7,.8),
                  
                  stringsAsFactors = F)



## Convert to percentage

#viz[,3:5] <- map(viz[,3:5], scales::percent) 



viz_lng <- viz %>% 
  
  gather(-c(1,2), key = category, value = importance)%>% 
  
  arrange(desc(importance))



ggplot(viz_lng[which(viz_lng$importance>0),], 
       
       aes(x = reorder_within(project, importance, category, ), 
           
           y= importance, group = project, fill = project)) +
  
  geom_bar(stat="identity") + 
  
  scale_x_reordered() +
  
  scale_y_continuous(label=scales::percent)+
  
  facet_wrap(vars(category, type), scales="free_x", ncol=2)  +
  
  guides(fill=FALSE) + theme_bw() +
  
  theme(strip.text = element_text(size = 14),
        
        axis.text.x = element_text(angle = 45, hjust = 1),
        
        legend.title = element_blank(),
        
        axis.text = element_text(size = 14),
        
        axis.title = element_text(size = 14)) 

1 Like

Thanks for work around solution.
Actually, I was wondering if this can also be done using facet_grid as well.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.