3

I'm a biology graduate student learning R. I was hoping someone could help me have the bars go horizontally in the opposite direction (the blue portion should start at 0 and the red at the 100 end of the scale).

Graph with bars in the wrong direction

enter image description here

Here is the data

my_species <- c('apomict_2-17-17_compreh', 'apomict_2-17-17_compreh', 'apomict_2-17-17_compreh', 'apomict_2-17-17_compreh', 'parthenogen_2-17-17_compreh', 'parthenogen_2-17-17_compreh', 'parthenogen_2-17-17_compreh', 'parthenogen_2-17-17_compreh', 'sexual_2-9-17', 'sexual_2-9-17', 'sexual_2-9-17', 'sexual_2-9-17')
my_species <- factor(my_species)
my_species <- factor(my_species,levels(my_species)[c(length(levels(my_species)):1)]) # reorder your species here just by changing the values in the vector :
my_percentage <- c(36.3, 56.3, 2.6, 4.8, 42.2, 50.6, 2.4, 4.8, 56.0, 19.9, 6.7, 17.4)
my_values <- c(522, 811, 38, 69, 608, 729, 35, 68, 806, 286, 96, 252)
category <- c(rep(c("S","D","F","M"),c(1)))
category <-factor(category)
category = factor(category,levels(category)[c(4,1,2,3)])
df = data.frame(my_species,my_percentage,my_values,category)

Here is the code:

# Load the required libraries
library(ggplot2)
library("grid")

# !!! CONFIGURE YOUR PLOT HERE !!! 
# Output
#my_output <- paste("/home/loki/","busco_figure.png",sep="/") 
my_width <- 20
my_height <- 15
my_unit <- "cm"

# Colors
my_colors <- c("#56B4E9", "#3492C7", "#F0E442", "#F04442")
# Bar height ratio
my_bar_height <- 0.75

# Legend
my_title <- "BUSCO Assessment Results"

# Font
my_family <- "sans"
my_size_ratio <- 1


# Code to produce the graph
labsize = 1
if (length(levels(my_species)) > 10){
 labsize = 0.66
}
print("Plotting the figure ...")


figure <- ggplot() +       
  geom_bar(aes(y = my_percentage, x = my_species, fill = category), data = df, stat="identity", width=my_bar_height) + 
  coord_flip() + 
  theme_gray(base_size = 8) + 
  #scale_y_continuous(labels = c("100","80","60","40","20","0"), breaks = c(100,80,60,40,20,0)) + 
  scale_y_continuous(labels = c("100","80","60","40","20","0"), breaks = c(100,80,60,40,20,0)) +
  #scale_y_continuous(labels = c("100","80","60","40","20","0"), breaks = c(0,20,40,60,80,100)) +
  scale_fill_manual(values = my_colors,labels =c(" Complete (C) and single-copy (S)  ",
                                                 " Complete (C) and duplicated (D)",
                                                 " Fragmented (F)  ",
                                                 " Missing (M)")) +   
  ggtitle(my_title) + 
  xlab("") + 
  ylab("\n%BUSCOs") + 

  theme(plot.title = element_text(family=my_family, colour = "black", size = rel(2.2)*my_size_ratio, face = "bold")) + 
  theme(legend.position="top",legend.title = element_blank()) + 
  theme(legend.text = element_text(family=my_family, size = rel(1.2)*my_size_ratio)) + 
  theme(panel.background = element_rect(color="#FFFFFF", fill="white")) + 
  theme(panel.grid.minor = element_blank()) + 
  theme(panel.grid.major = element_blank()) +
  theme(axis.text.y = element_text(family=my_family, colour = "black", size = rel(1.66)*my_size_ratio)) + 
  theme(axis.text.x = element_text(family=my_family, colour = "black", size = rel(1.66)*my_size_ratio)) + 
  theme(axis.line = element_line(size=1*my_size_ratio, colour = "black")) + 
  theme(axis.ticks.length = unit(.85, "cm")) + 
  theme(axis.ticks.y = element_line(colour="white", size = 0)) + 
  theme(axis.ticks.x = element_line(colour="#222222")) + 
  theme(axis.ticks.length = unit(0.4, "cm")) + 
  theme(axis.title.x = element_text(family=my_family, size=rel(1.2)*my_size_ratio)) + 

  guides(fill = guide_legend(override.aes = list(colour = NULL))) +
  guides(fill=guide_legend(nrow=2,byrow=TRUE))

  for(i in rev(c(1:length(levels(my_species))))){
    detailed_values <- my_values[my_species==my_species[my_species==levels(my_species)[i]]]
    total_buscos <- sum(detailed_values)
    figure <- figure + 
    annotate("text", label=paste("C:", detailed_values[1] + detailed_values[2], " [S:", detailed_values[1], ", D:", detailed_values[2], "], F:", detailed_values[3], ", M:", detailed_values[4], ", n:", total_buscos, sep=""), 
             y=3, x = i, size = labsize*4*my_size_ratio, colour = "black", hjust=0, family=my_family)
  }

my_output="~/temp.png"
ggsave(figure, file=my_output, width = my_width, height = my_height, unit = my_unit)
print("Done")
user20650
  • 24,654
  • 5
  • 56
  • 91
Loki
  • 33
  • 4
  • Please see http://stackoverflow.com/a/34637703/2109767. Looking at your code I think that answer should achieve what you want. – Jeremy Farrell Mar 24 '17 at 23:33
  • Thank you. I'll let you know! – Loki Mar 24 '17 at 23:49
  • I'm sorry but that post did not seem to achieve what I want (unless I just couldn't implement it correctly). I'm new to R and most of this R script was generated by the busco python script. I'm just wanting the entire bars including colored components to flip horizontally. – Loki Mar 25 '17 at 00:25
  • No problem, I was trying to point you in the right direction because I didn't have time to provide a full answer. Please see my answer below, hopefully it helps you create your plot as needed. – Jeremy Farrell Mar 25 '17 at 00:57

2 Answers2

7

see ?position_stack:

position_fill() and position_stack() automatically stack values in reverse order of the group aesthetic, which for bar charts is usually defined by the fill aesthetic (the default group aesthetic is formed by the combination of all discrete aesthetics except for x and y). This default ensures that bar colours align with the default legend.

In order to change the stacking direction, you simply need to add position = position_stack(reverse = TRUE) to geom_bar:

figure <- ggplot() +       
    geom_bar(
        aes(y = my_percentage, x = my_species, fill = category),
        data = df, stat="identity", width=my_bar_height,
        position = position_stack(reverse = TRUE)) + 
    coord_flip() + 
...

enter image description here

If you don't want to use position_stack, you would have to change factor level and You also have to set filling color breaks to maintain the same legend order.

mt1022
  • 16,834
  • 5
  • 48
  • 71
2

You need to reorder the factor levels in order for ggplot2 to know what to do. Here is an example of that (note I had to reorder the labels and colors as well):

...
# Colors
my_colors <- c( "#F04442", "#F0E442", "#3492C7", "#56B4E9")
...
df$category = ordered(df$category, levels = c("M", "F", "D", "S"))

figure <- ggplot(data = df[order(df$category, decreasing = F),]) +       
  geom_bar(aes(y = my_percentage, x = my_species, fill = category), stat="identity", width=my_bar_height) + 
  coord_flip() + 
  theme_gray(base_size = 8) + 
  scale_y_continuous(labels = c("100","80","60","40","20","0"), breaks = c(100,80,60,40,20,0)) +
  scale_fill_manual(values = my_colors,labels =c(" Missing (M)", 
                                                 " Fragmented (F)  ",
                                                 " Complete (C) and duplicated (D)",
                                                 " Complete (C) and single-copy (S)  ")) +   
...
Jeremy Farrell
  • 1,481
  • 14
  • 16
  • @mt1022's answer is more straightforward, but I figured I would leave this here as it still presents another way of achieving this. – Jeremy Farrell Mar 25 '17 at 01:25