1

Goal is to achieve ordered categories on y axis.

y1 -> y2 -> y3.

Here's the example:

require(data.table)
require(ggplot2)

dt <- data.table(var = rep("x1", 3),
                 categ = paste0("y", c(1,2,3)),
                 value = c(-2,0.5,-1))

ggplot(dt, aes(x = categ, y = value)) +
    geom_bar(stat = "identity") +
    coord_flip() +
    theme_bw()

enter image description here

It seems to be reversed. Here's the one way to achieve desired ordering in ggplot2:

dt$categ <- factor(dt$categ, levels = rev(levels(factor(dt$categ))))

ggplot(dt, aes(x = categ, y = value)) +
    geom_bar(stat = "identity") +
    coord_flip() +
    theme_bw()

enter image description here

Great, now ordering seems to be right. But with some modifications:

ggplot(dt, aes(x = categ, y = value)) +
    geom_bar(data = dt[value < 0], stat = "identity", fill = "darkred") +
    geom_bar(data = dt[value >= 0], stat = "identity", fill = "darkblue") +
    coord_flip() +
    theme_bw()

enter image description here

For some reason factor ordering is ignored here. Any clues why?

pogibas
  • 27,303
  • 19
  • 84
  • 117
statespace
  • 1,644
  • 17
  • 25

1 Answers1

0

Solution could be:

# dt is original data without factors
ggplot(dt, aes(categ, value, fill = value >= 0)) +
  geom_bar(stat = "identity") +
  scale_fill_manual(values = c("darkred", "darkblue")) +
  # since we want y1 on top and y3 on bottom we have to apply rev
  scale_x_discrete(limits = rev(dt$categ)) +
  coord_flip() +
  theme_bw()

Trick is to pass dt$categ as limits argument to scale_x_discrete(). In your first plot order is not reversed, this is how it should be as ggplot2 starts putting values from the origin of the axis (0).

enter image description here

I also removed two geom_bar lines that were used in a not-ggplot way.

pogibas
  • 27,303
  • 19
  • 84
  • 117
  • The difference in the order between plot 2 and 3 from the question comes from the fact that, as @PoGibas pointed out, using two geom_bars with different color is not how you should do things with ggplot! – jkd Jul 11 '19 at 11:12
  • Setting the limits in `scale_x_discrete` makes the ordering of the factor superfluous but is not necessary to solve your problem (as you already put your factor levels in the correct order). So you need either the `scale_x_discrete(...)` **or** `dt$categ <- factor(..., levels = ...)`. – jkd Jul 11 '19 at 11:14
  • I might have oversimplified my example little bit too much, but some points mentioned in answer have indeed helped. There are more issues when you add two more dimensions and make `facet_grid`. I suppose I should re-formulate question and create a better example. – statespace Jul 11 '19 at 12:00