2

I'm trying to make a plot with a line and two ribbons for each of three factor levels (factor named block). This is my call to ggplot2:

ggplot(df, aes(x = x, y = y, fill = block, color = block)) +
  geom_ribbon(aes(ymin = llb, ymax = uub), alpha = .1, color = NA) +
  geom_ribbon(aes(ymin = lb, ymax = ub), alpha = .5, color = NA) +
  geom_line(size = 2)

This is what I get: graph a better example added in later edit

As you can see in the picture, this is the order of plotting:

  1. Light red ribbon
  2. Light blue ribbon
  3. Light green ribbon
  4. Dark red ribbon
  5. Dark blue ribbon
  6. Dark green ribbon
  7. Red line
  8. Blue line
  9. Green line

This is ugly. I want to plot the line and two ribbons for the first factor level first, then all of those for the second level, and then the third. Or, more explicitly, plot in this order:

  1. Light red ribbon
  2. Dark red ribbon
  3. Red line
  4. Light blue ribbon
  5. Blue line
  6. Dark blue ribbon
  7. Light green ribbon
  8. Dark green ribbon
  9. Green line

Any ideas on doing so without subsetting the data by factor and manually calling the geoms three times? Perhaps an easy way to group three geoms into a new geom?

Thanks!

YanivA
  • 21
  • 5

1 Answers1

1

When the fill color is determined automatically, it is assigned based on the level of the factor.

Consider a density plot of the following sample data:

set.seed(3)
data <- data.frame(factor = rep(LETTERS[1:3],each = 50),
                   value = c(rnorm(n = 50, mean = 5, sd = 4),
                             rnorm(n = 50, mean = 10, sd = 4),
                             rnorm(n = 50, mean = 15, sd = 4)))

library(ggplot)
ggplot(data, aes(x = value, fill = factor)) +
  geom_density(color = NA)

enter image description here

If we add a call to scale_fill_manual and provide values, we can reverse the order of the colors:

ggplot(data, aes(x = value, fill = factor)) +
  geom_density(color = NA) +
  scale_fill_manual(values = c("#619CFF","#00BA38","#F8766D"))

enter image description here

If we combine this with factor re-ordering, with factor(x, levels = y) we can also change the factor that is plotted on top:

ggplot(data, aes(x = value, fill = factor(factor, levels = c("C","B","A")))) +
  geom_density(color = NA) + labs(fill = "factor") +
  scale_fill_manual(values = c("#619CFF","#00BA38","#F8766D")) + 
  guides(fill = guide_legend(reverse = TRUE))

enter image description here

Ian Campbell
  • 23,484
  • 14
  • 36
  • 57
  • Thanks for you answer! That is how to reorder plotting with a single geom. I indeed use `factor` to choose my factor ordering. However - this does not solve the problem of plotting multiple geoms by factor order rather than by geom order. – YanivA Jun 03 '20 at 11:23
  • Hi YanivA, I don't understand what you're asking then. Perhaps you can [edit your question](https://stackoverflow.com/posts/62131966/edit) with clarification and a sample of your data. – Ian Campbell Jun 03 '20 at 12:05
  • Thanks for your reply! I edited the question with the explicit order the geoms are being plotted right now, and the desired order. I also added a clearer example graph. – YanivA Jun 09 '20 at 01:28