Search code examples
rggplot2geom-bar

Horizontal geom_bar with no overlaps, equal bar widths, and customized axis tick labels


Probably a simple ggplot2 question.

I have a data.frame with a numeric value, a categorical (factor) value, and a character value:

library(dplyr)
set.seed(1)
df <- data.frame(log10.p.value=c(-2.5,-2.5,-2.5,-2.39,-2,-1.85,-1.6,-1.3,-1.3,-1),
                 direction=sample(c("up","down"),10,replace = T),
                 label=paste0("label",1:10),stringsAsFactors = F) %>% dplyr::arrange(log10.p.value)
df$direction <- factor(df$direction,levels=c("up","down"))

I want to plot these data as a barplot using geom_bar, where the bars are horizontal and their lengths are determined by df$log10.p.value, their color by df$direction, and the y-axis tick labels are df$label, where the bars are vertically ordered by df$log10.p.value.

As you can see df$log10.p.value are not unique, hence:

ggplot(df,aes(log10.p.value))+geom_bar(aes(fill=direction))+theme_minimal()+coord_flip()+ylab("log10(p-value)")+xlab("")

Gives me: enter image description here

How do I:

  1. Make the bars not overlap each other.
  2. Have the same width.
  3. Be separated by a small margin?
  4. Have the y-axis tick labels be df$label?

Thanks


Solution

  • Here is one possible solution. Please note that, by default, geom_bar determines the bar length using frequency/count. So, you need to specify stat = "identity" for value mapping.

    # since all of your values are negative the graph is on the left side
    ggplot(df, aes(x = label, y = log10.p.value, fill = direction)) +
      geom_bar(stat = "identity") +
      theme_minimal() +
      coord_flip() + 
      ylab("log10(p-value)") +
      xlab("")