Creating Alluvial Diagrams (original) (raw)
Hiding
With alluvial sometimes it is desirable to hide omit plotting some of the alluvia. This is most frequently the case with larger datasets in which there are a lot of combinations of values of the variables associated with very small frequencies, or even 0s. Alluvia can be hidden with argument hide expecting a logical vector of length equal to the number of rows in the data. Alluvia for which hide is FALSE are not plotted. For example, to hide alluvia with frequency less than 150:
alluvial(tit2d[,1:2], freq=tit2d$n, hide=tit2d$n < 150)This skips drawing the alluvia corresponding to the following rows in tit data frame:
tit2d %>% select(Class, Survived, n) %>%
filter(n < 150)## Source: local data frame [2 x 3]
## Groups: Class [2]
##
## Class Survived n
## <chr> <chr> <dbl>
## 1 1st No 122
## 2 2nd Yes 118You can see the gaps e.g. on the “Yes” and “No” category blocks on the Survived axis.
If you would rather omit these rows from the plot alltogether (i.e. no gaps), you need to filter your data before it is used by alluvial().
Changing “layers”
By default alluvia are plotted in the same order in which the rows are ordered in the dataset.
Consider simple data:
d <- data.frame(
x = c(1, 2, 3),
y = c(3 ,2, 1),
freq=c(1,1,1)
)
d## x y freq
## 1 1 3 1
## 2 2 2 1
## 3 3 1 1As there are three rows, we will have three alluvia:
alluvial(d[,1:2], freq=d$freq, col=1:3, alpha=1)
# Reversing the order
alluvial(d[ 3:1, 1:2 ], freq=d$freq, col=3:1, alpha=1)Note that to keep colors matched in the same way to the alluvia we had to reverse the col argument too. Instead of reordering the data and keeping track of the other arguments plotting order can be adjusted with layer argument:
alluvial(d[,1:2], freq=d$freq, col=1:3, alpha=1,
layer=3:1)The value of layer is passed to order so it is possible to use logical vectors e.g. if you only want to put some of the flows on top. For example, for Titanic data to put all alluvia for all survivors on top we can:
alluvial(tit3d[,1:3], freq=tit3d$n,
col = ifelse( tit3d$Survived == "Yes", "orange", "grey" ),
alpha = 0.8,
layer = tit3d$Survived == "No"
)First layer is the one on top, second layer below the first and so on. Consequently, in the example above, Survived == "No" is ordered after Survived == "Yes" so the former is below the latter.
Adjusting vertical order
This is feature is experimental!
Usually the order of the variables (axes) is rather unimportant. However, having particular two variables next to each other facilitates analyzing dependency between those two variables. In alluvial diagrams the ordering of the variables determines the vertical plotting order of the alluvia. This vertical order, together with setting blocks to FALSE, can be used to turn category blocks into stacked barcharts.
Consider two versions of subsets of the Titanic data that differ only in the order of variables.
tit %>% group_by(Sex, Age, Survived) %>%
summarise( n= sum(Freq)) -> x
tit %>% group_by(Survived, Age, Sex) %>%
summarise( n= sum(Freq)) -> yIn x we have Sex-Age-Survived-n while in y we have Survived-Age-Sex-n.
If we color the alluvia according to the first axis, the category blocks of Age and Survived become barcharts showing relative frequencies of Men and Women within categories of Age and Survived.
alluvial(x[,1:3], freq=x$n,
col = ifelse(x$Sex == "Male", "orange", "grey"),
alpha = 0.8,
blocks=FALSE
)Now we can see for example that
- There were a little bit of more girls than boys (category
Age == "Child") - Among surviors there were roughly the same number of Men and Women.
Argument ordering can be used to fully customize the ordering of each alluvium on each axis without the need to reorder the axes themselves. This feature is experimental as you can easily break things. It expects a list of numeric vectors or NULLs one for each variable in the data:
- Value
NULLdoes not change the default order on the corresponding axis. - A numeric vector should have length equal to the number of rows in the data and is determines the vertical order of the alluvia on the corresponding axis.
For example:
alluvial(y[,1:3], freq=y$n,
# col = RColorBrewer::brewer.pal(8, "Set1"),
col = ifelse(y$Sex == "Male", "orange", "grey"),
alpha = 0.8,
blocks = FALSE,
ordering = list(
order(y$Survived, y$Sex == "Male"),
order(y$Age, y$Sex == "Male"),
NULL
)
)The list passed to ordering has has three elements corresponding to Survived, Age, and Sex respectively (that’s the order of the variables in y). The elements of this list are
- Call to
ordersorting the alluvia on theSurvivedaxis. The alluvia need to be sorted according toSurvivedfirst (otherwise the categories “Yes” and “No” will be destroyed) and according to theSexsecond. - Call to
ordersorting the alluvia on theAgeaxis. The alluvia need to be sorted according toAgefirstSexsecond. NULLleaves the default ordering onSexaxis.
In the example below alluvia are colored by sex (red=Female, blue=Male) and survival status (bright=survived, dark=did not survive). Each category block is a stacked barchart showing relative freuquencies of man/women who did/did not survive. The alluvia are reordered on the last axis (Age) so that Sex categories are next each other (red together and blue together):
pal <- c("red4", "lightskyblue4", "red", "lightskyblue")
tit %>%
mutate(
ss = paste(Survived, Sex),
k = pal[ match(ss, sort(unique(ss))) ]
) -> tit
alluvial(tit[,c(4,2,3)], freq=tit$Freq,
hide = tit$Freq < 10,
col = tit$k,
border = tit$k,
blocks=FALSE,
ordering = list(
NULL,
NULL,
order(tit$Age, tit$Sex )
)
)