Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Barplot with both stacked and grouped options, without face grid

I am trying to make a stacked and grouped barplot using the following datasets:

dfplot  <- data.frame(organisms=c("M.musculus","D.melanogaster" ,"H.sapiens","O.sativa","S.pombe","C.familiaris",
           "G.gallus","P.falciparum","A.thaliana","C.elegans","D.rerio","B.taurus","S.cerevisiae","R.norvegicus","C.intestinalis","B.subtilis","E.coli"),                  
                      KEGGv2=c(20,7,21,126,106,62,26,80,5,5,13,306,8,35,32,104,107), 
                      KEGGv1=c(286,124,289,0,0,244,135,0,121,124,148,0,101,271,87,0,0),
                      Reactome=c(358,146,596,115,54,306,370,23,155,112,365,341,52,364,0,0,0))

# Melt the dataframe
melted <- melt(dfplot, "organisms")

# Reformat the data labels
melted$cat <- ''
melted[melted$variable == 'Reactome',]$cat <- "Reactome"
melted[melted$variable != 'Reactome',]$cat <- "KEGG"


ggplot(melted, aes(x=cat, y=value, fill=variable)) + 
  geom_bar(stat = 'identity', position = 'stack') +
  facet_grid(~ organisms)+ 
  scale_fill_manual(values=c("deepskyblue4", "lightblue1", "olivedrab2")) +
  labs(y = "Number of Pathways") +
  theme(axis.title.x=element_blank(),
        axis.text.x=element_blank(),
        axis.ticks.x=element_blank(),
        legend.title=element_blank(),
        strip.text.x = element_blank(),
        strip.background = element_blank(),
        panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        panel.background = element_blank(),
        axis.line = element_line(colour = "black"))

And my output is the following one:

enter image description here

I used a facet_grid per organism because I wanted to have a mix between stack (for both KEGGv1 and KEGGv2) and then group it with the other group Reactome. However, when doing the melting, the x-axis will have two labels per facet_grid (KEGG and Reactome, which is the variable obtained from the melting [cat]). I did not want that label so I remove them.

What I am trying to do is to have the organism name per each of the groupings, so each of the 17 grouping bars will have the name of the corresponding organism**. Therefore, I am missing that, I have tried several ways but I cannot find the proper way of doing it.

Thanks in advance,

like image 720
Maik Avatar asked Nov 18 '25 16:11

Maik


1 Answers

You can do two things to make this work:

  1. Rotate the labels of the facet so that they plot at 90 degrees
  2. Plot the facet labels beneath the graph using the switch = 'x' argument within facet_grid.

Here is the complete example:

  ggplot(melted, aes(x=cat, y=value, fill=variable)) + 
    geom_bar(stat = 'identity', position = 'stack') +
    facet_grid(~organisms, switch = 'x')+ 
    scale_fill_manual(values=c("deepskyblue4", "lightblue1", "olivedrab2")) +
    labs(y = "Number of Pathways") +
    theme(axis.title.x=element_blank(),
          axis.text.x=element_blank(),
          axis.ticks.x=element_blank(),
          legend.title=element_blank(),
          panel.grid.major = element_blank(),
          panel.grid.minor = element_blank(),
          panel.background = element_blank(),
          axis.line.y = element_line(colour = "black"),
          strip.text = element_text(angle = 90))

enter image description here

I left the default shaded background, but you can easily style as you prefer.

Aproach Two

You might want to consider rotating the plot. This requires you to flip the coordinates of the plot using coord_flip before the facet is called. As we are faceting in the other direction we change the facet argument to facet_grid(organisms~.). All other arguments which refer to x or y are swapped over:

  ggplot(melted, aes(x=cat, y=value, fill=variable)) + 
    geom_bar(stat = 'identity', position = 'stack') +
    coord_flip() +
    facet_grid(organisms~., switch = 'y')  +
    scale_fill_manual(values=c("deepskyblue4", "lightblue1", "olivedrab2")) +
    labs(y = "Number of Pathways") +
    theme(axis.title.y=element_blank(),
          axis.text.y=element_blank(),
          axis.ticks.y=element_blank(),
          legend.title=element_blank(),
          panel.grid.major = element_blank(),
          panel.grid.minor = element_blank(),
          panel.background = element_blank(),
          axis.line.x = element_line(colour = "black"),
          strip.text.y = element_text(angle = 180))

enter image description here

like image 172
Michael Harper Avatar answered Nov 21 '25 06:11

Michael Harper