rdataframeggplot2streamggalluvial

ggalluvial: How to order the lines between blocks to be in same order as your data.frame?


I have made an alluvia plot using the ggalluvial package in R. I am trying to order the flows (lines between blocks) so that they are much easier to read - I am aiming for them to be stacked on top of each other (orange color, followed by purple color) in each section for each block. Here I am defining a block to be the vertical bars that sit on the x-axis in positions 1, 2, and 3. Additionally, it is placing the text in inappropriate places within each block.

Reproducible Example

#Making the data.frame

w <- c("Rain Forest", "Desert", "Arctic", "City", "Low Earth", "Boonies", "Space")
x <- 1:40
y <- c("Bird", "Tiger", "Cat", "Parrot", "T-Rex", "Dreadwing")

set.seed(0)
GenComp <- data.frame(
  Location = sample(w, size = 28, replace = TRUE),
  Frequency = sample(x = x, size = 28, replace = TRUE),
  Animal = sample(x = y, size = 28, replace = TRUE),
  Gender = rep(c("Male", "Female"), 14))

GenComp <- GenComp[order(GenComp$Gender, GenComp$Animal, GenComp$Location, decreasing = FALSE),]
row.names(GenComp) <- 1:nrow(GenComp)

GenComp$Location <- factor(GenComp$Location, levels = sort(unique(GenComp$Location)))
GenComp$Gender <- factor(GenComp$Gender, levels = c("Female", "Male"))
GenComp$Animal <- factor(GenComp$Animal, levels = sort(unique(GenComp$Animal)))
GenComp <- GenComp[, c(4, 3, 1, 2)]

#Graphing

library(ggalluvial)
ggplot(GenComp,aes(y = Frequency,
                            axis1 = Gender, axis2 = Animal, axis3 = Location)) + 
  geom_alluvium(aes(fill = Gender), width = 1/8, knot.pos = 0, reverse = FALSE) +
  geom_stratum(alpha = 0.25, width = 1/8, reverse = FALSE) +
  geom_text(stat = "stratum", aes(label = after_stat(stratum)), reverse = TRUE, size = 3)  +
  ggtitle("Distribution of Fauna") +
  scale_fill_manual(values = c(Female = "#691869", Male = "#EBBC55")) +
  guides(fill = "none") 

Here is the graph: Alluvia_FlowLines

The red arrows point to the text that is being written where they are not supposed to be. The blue circles are an example of what I don't want - circles show a mix of yellow and purple lines. I would like to always keep the yellow lines on top and purple under the yellow for each section of each block.

Trying to make sense of things, I learned in this post Ordering of streams within each block that 'the order of the streams in alluvial()is controlled by the row order. This is why I have ordered the GenComp data.frame in the order I would like to see the alluvia graph GenComp <- GenComp[order(GenComp$Gender, GenComp$Animal,GenComp$Location, decreasing = FALSE),] ; row.names(GenComp) <- 1:nrow(GenComp).

However, in the ggplot2 version, even if I reorder the rows, I get the same plot. A work around was the implementation of the commands lode_favor and lode_order.

If this is the answer, how can I implement these commands with ggalluvia in the code above?

I also learned here: ggalluvial - let order of stratums follow dataset that "you can re-order the axes by converting your character vectors to factors and specifying the levels you want." Which is why I have the factor(..., levels = ()) specified in the above code. This also did not work.

I read here: The Order of the Rectangles under the section: "Manual lode ordering" that "we can pass a vector that puts the cases in the order of their IDs in the data at every axis" and the vector can be passed in the stat_alluvium() command. However, adding the following commands to the code above (assigning the order: lode_ord <- 1:28and adding stat_alluvium(aes(order = lode_ord)) into the code above made a horrific mess of the graph - it inserted gray lines, reduced the color of the flows ... just horrid.

Any ideas on what I can do to 1) fix the text issue and 2) organize the lines in such a way that the yellow lines always stack on top of the purple lines for each section in each block?


Solution

  • The option you're looking for is lode.guidance = "forward":

    ggplot(GenComp,aes(y = Frequency,
                                axis1 = Gender, axis2 = Animal, axis3 = Location)) + 
      geom_alluvium(lode.guidance = "forward", aes(fill = Gender), width = 1/8, knot.pos = 0, reverse = FALSE) +
      geom_stratum(alpha = 0.25, width = 1/8, reverse = FALSE) +
      geom_text(stat = "stratum", aes(label = after_stat(stratum)), reverse = TRUE, size = 3)  +
      ggtitle("Distribution of Fauna") +
      scale_fill_manual(values = c(Female = "#691869", Male = "#EBBC55")) +
      guides(fill = "none") 
    

    Alluvial plot of animals