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")
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:28
and 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?
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")