How to get percentages on the y axes in an alluvial or sankey plot?

Viewed 1028

Ggplot2 alluvial

I realized this graph using ggplot2 and I'd like to change y axes to percentages, from 0% to 100% with breaks every 10. I know I can use:

+ scale_y_continuous(label=percent, breaks = seq(0,1,.1))

but I still get a problem because, turning into percentages, R interpret 30000 as 30000%, so if a limit to 100% I don't get anything in my graph. How can I manage it?

I have a dataset like this:

ID time value
1   1   B with G available
2   1   Generic
3   1   B with G available
4   1   Generic
5   1   B with G available
6   1   Generic
7   1   Generic
8   1   Generic
9   1   B with G available
10  1   B with G available
11  1   Generic
12  1   B with G available
13  1   B with G available
14  1   B with G available
15  1   Generic
16  1   B with G available
17  1   B with G available
18  1   B with G available
19  1   B with G available
20  1   B with G available
1   2   B with G available
2   2   Generic
3   2   B with G available
4   2   Generic
5   2   B with G available
6   2   Generic
7   2   Generic
8   2   Generic
9   2   B with G available
10  2   B with G available
11  2   Generic
12  2   B with G available
13  2   B with G available
14  2   B with G available
15  2   Generic
16  2   B with G available
17  2   switch
18  2   B with G available
19  2   B with G available
20  2   switch

which is reproducible with this code:

PIPPO <- data.frame("ID"=rep(c(1:20),2), "time"=c(rep(1,20),rep(2,20)), "value"=c("B","G","B","G","B",rep("G",3),rep("B",2),"G",rep("B",3),"G",rep("B",6),"G","B","G","B",rep("G",3),rep("B",2),"G",rep("B",3),"G","B","switch",rep("B",2),"switch"))

so I don't have a variable for y axes I can manage.

Here my code and the plot I obtained

ggplot(PIPPO, 
       aes(x = time, stratum = value, alluvium = ID,
           fill = value, label = value)) +
  scale_fill_brewer(type = "qual" , palette = "Set3") +
  geom_flow(stat = "flow", knot.pos = 1/4, aes.flow = "forward",
            color = "gray") + 
  geom_stratum() +
  theme(legend.position = "bottom") 

enter image description here

Could anyone help me?

What I get on real data using

scale_y_continuous(label = scales::percent_format(scale = 100 / n_id))

is this: enter image description here

with 84% as the maximum value (and not 100%). How can i get the y-axes up to 100% and broken every 10% ?

Here what I get with

scale_y_continuous(breaks = scales::pretty_breaks(10), label = scales::percent_format(scale = 100 / n_id))

enter image description here

I get this weird values every 14%.

3 Answers

Using the scale argument in percent_format this can be achieved like so:

PIPPO <- data.frame("ID"=rep(c(1:20),2), "time"=c(rep(1,20),rep(2,20)), "value"=c("B","G","B","G","B",rep("G",3),rep("B",2),"G",rep("B",3),"G",rep("B",6),"G","B","G","B",rep("G",3),rep("B",2),"G",rep("B",3),"G","B","switch",rep("B",2),"switch"))

library(ggplot2)
library(ggalluvial)

n_id <- length(unique(PIPPO$ID))

ggplot(PIPPO, 
       aes(x = time, stratum = value, alluvium = ID,
           fill = value, label = value)) +
  scale_fill_brewer(type = "qual" , palette = "Set3") +
  scale_y_continuous(label = scales::percent_format(scale = 100 / n_id)) +
  geom_flow(stat = "flow", knot.pos = 1/4, aes.flow = "forward", color = "gray",) + 
  geom_stratum() +
  theme(legend.position = "bottom") 

Created on 2020-05-19 by the reprex package (v0.3.0)

I assume You will need to create a new column of the percentages, by taking the total number of rows, and then dividing each "value" in your column by the total to get what percentage it represents.

Simply normalising your y-values seems to do the trick:

library(ggplot2)

ggplot(mtcars, aes(x = cyl, y = mpg/max(mpg))) +
  geom_point() +
  scale_y_continuous(label = scales::label_percent())

Created on 2020-05-19 by the reprex package (v0.3.0)

Related