Search code examples
rggplot2ggalluvial

Using ggalluvial, how can I color one stratum box and leave all others white


I am trying to create an alluvial plot with ggalluvial where the terminal stratum box color is the colors of the flows. I am unfortunately unable to keep other stratum colors from changing either to a new color level NA ("grey") or to define as a my preferred "white" without showing up in the legend.

Here is some example data and my first plot, where flows are correctly colored according to the terminal stratum:

library(ggalluvial)

dat <- expand.grid(lev1 = LETTERS[1:3], lev2 = letters[1:3], bin = as.character(1:3))
set.seed(1111)
dat$value <- rpois(n = nrow(dat), lambda = 3)
dat

dat <- dat[order(dat$bin, dat$lev1, dat$lev2),]

ggplot(data = dat) + aes(axis1 = lev1, axis2 = lev2, axis3 = bin, y = value) + 
  geom_alluvium(aes(fill = bin)) +
  geom_stratum() +
  geom_text(stat = "stratum", aes(label = after_stat(stratum)), size = 3) + 
  scale_x_discrete(limits = c("lev1", "lev2", "bin"), expand = c(.15, .05)) +
  theme(text = element_text(size = 9),
    axis.text.x = element_text(angle = 90, hjust = 0, vjust = 0.3, size = 9))

enter image description here

When I try to add geom_stratum(aes(fill = bin)), the other strata also get colored by a new color level, NA:

ggplot(data = dat) + aes(axis1 = lev1, axis2 = lev2, axis3 = bin, y = value) + 
  geom_alluvium(aes(fill = bin)) +
  geom_stratum(aes(fill = bin)) +
  geom_text(stat = "stratum", aes(label = after_stat(stratum)), size = 3) + 
  scale_x_discrete(limits = c("lev1", "lev2", "bin"), expand = c(.15, .05)) +
  theme(text = element_text(size = 9),
    axis.text.x = element_text(angle = 90, hjust = 0, vjust = 0.3, size = 9))

enter image description here

Assigning colors manually and specifying na.translate = FALSE gets rid of the new NA color level, but also removed the white fill from those other stratum fills.

colorfill <- 2:4
ggplot(data = dat) + aes(axis1 = lev1, axis2 = lev2, axis3 = bin, y = value) + 
  geom_alluvium(aes(fill = bin)) +
  geom_stratum(aes(fill = bin)) +
  scale_fill_manual(values = colorfill, na.translate = FALSE) +
  geom_text(stat = "stratum", aes(label = after_stat(stratum)), size = 3) + 
  scale_x_discrete(limits = c("lev1", "lev2", "bin"), expand = c(.15, .05)) +
  theme(text = element_text(size = 9),
    axis.text.x = element_text(angle = 90, hjust = 0, vjust = 0.3, size = 9))

enter image description here


Solution

  • One option to achieve your desired result would be to set the na.value= to "white" and get rid of the NA in the legend via the limits= of the fill scale:

    library(ggalluvial)
    
    ggplot(data = dat) +
      aes(axis1 = lev1, axis2 = lev2, axis3 = bin, y = value) +
      geom_alluvium(
        aes(fill = bin)
      ) +
      geom_stratum(
        aes(fill = bin)
      ) +
      scale_fill_discrete(na.value = "white", limits = \(x) x[!is.na(x)]) +
      geom_text(stat = "stratum", aes(label = after_stat(stratum)), size = 3) +
      scale_x_discrete(limits = c("lev1", "lev2", "bin"), expand = c(.15, .05)) +
      theme(
        text = element_text(size = 9),
        axis.text.x = element_text(angle = 90, hjust = 0, vjust = 0.3, size = 9)
      )