I have been trying to create a stacked bar plot, where the colors of the plot relate to those in a map. Basically, I have proportion of an area covered by a given polygon. I have sorted my df in advance so the stacks Proportion
are in decreasing order per each Class
. It works ok if a set the values of the fill as a continuos variable i.e. Cluster
(but then I can't change particular colors of the stack), and if I convert them into factors Clu
then the order of the stacks is lost or I can manage to sort them but for the whole graph not for each class... The same Cluster
can occur in different classes i.e. cluster Two
Num Class Cluster Proportion Clu Order consec
1 9 Class_9 2 0.859 Two 1 1
2 9 Class_9 5 0.141 Five 2 2
3 10 Class_10 2 0.622 Two 1 3
4 10 Class_10 1 0.179 One 2 4
5 10 Class_10 7 0.165 Seven 3 5
6 10 Class_10 6 0.034 Six 4 6
7 11 Class_11 7 1.000 Seven 1 7
8 12 Class_12 2 0.571 Two 1 8
9 12 Class_12 8 0.289 Eight 2 9
10 12 Class_12 1 0.140 One 3 10
11 13 Class_13 8 0.581 Eight 1 11
12 13 Class_13 4 0.210 Four 2 12
13 13 Class_13 2 0.112 Two 3 13
14 13 Class_13 3 0.079 Three 4 14
15 13 Class_13 5 0.018 Five 5 15
I have managed to go this far with the code.
cols<-c(One='Blue',Two='Red',Three='Yellow',Four='lightblue',Five='darkgrey',Six='Black', Seven='cyan',Eight='Green')
ggplot(Tx, aes(x=Class, y=Proportion, fill= Clu)) +
geom_col(width = .7, colour="black", lwd=0.1) +
geom_text(aes(label=ifelse(Proportion >= 0.05, sprintf("%.2f",Proportion),"")),
position=position_stack(vjust=0.5), colour="white") +
coord_flip() +
scale_y_continuous(labels = function(y) paste0(y))+
scale_fill_manual(values = cols)+
labs(y="", x="")
To summarize, I would like to have a graph with the proportions in increasing order for each class, but with the colors I specify for each clusters
One option (a little different than what you were thinking) is to use position.dodge
and tidytext::reorder_within
.
library(tidyverse)
library(tidytext)
cols<-c('Blue','Red','Yellow','lightblue','darkgrey','Black', 'cyan', 'Green')
Tx %>%
mutate(Cluster2 = reorder_within(Cluster, Proportion, Class)) %>%
ggplot(aes(Cluster2, Proportion, fill = as.factor(Cluster))) +
geom_col(position = position_dodge2(preserve = "single")) +
scale_x_reordered() +
scale_fill_manual(values = cols) +
coord_flip() +
facet_grid(Class~., scales = 'free_y', space = 'free')
If you really need the stacked bars with the different orders, another option is to generate the plot for each class separately (which allows for the correct order) and then stack them all back together. This can be done using cowplot::plot_grid
and cowplot::get_legend
.
Generate list of plots with correct order and stack them into one plot.
library(tidyverse)
library(cowplot)
Tx2 <- Tx %>%
mutate(Cluster = factor(Cluster))
cols<-c(One='Blue',Two='Red',Three='Yellow',Four='lightblue',Five='darkgrey',Six='Black', Seven='cyan',Eight='Green')
p_list <- lapply(unique(Tx2$Class), function(x){
p <- Tx2 %>%
filter(Class == x) %>%
ggplot(aes(Class, Proportion, fill = reorder(Clu, -Proportion))) +
geom_col(color = 'black') +
geom_text(aes(label=ifelse(Proportion >= 0.05, sprintf("%.2f",Proportion),"")),
position=position_stack(vjust=0.5),
color = 'white') +
coord_flip() +
scale_fill_manual(values = cols) +
labs(x = NULL, y = NULL) +
theme_minimal() +
theme(legend.position = 'none')
if (x != 'Class_13') p <- p + theme(axis.text.x = element_blank())
p
})
p_col <- plot_grid(plotlist = p_list,
ncol = 1,
align = 'v',
rel_heights = c(rep(1,4), 1.2))
Generate the legend to be used.
p <- ggplot(Tx2, aes(Class, Proportion, fill = reorder(Clu, as.numeric(Cluster)))) +
geom_col(color = 'black') +
scale_fill_manual(values = cols, labels= 1:8, name = 'Cluster')
l <- cowplot::get_legend(p)
Put the stacked plots and the legend together.
plot_grid(p_col, l, rel_widths = c(3, .4))
Data
Tx <- read.table(text =
' Num Class Cluster Proportion Clu Order consec
1 9 Class_9 2 0.859 Two 1 1
2 9 Class_9 5 0.141 Five 2 2
3 10 Class_10 2 0.622 Two 1 3
4 10 Class_10 1 0.179 One 2 4
5 10 Class_10 7 0.165 Seven 3 5
6 10 Class_10 6 0.034 Six 4 6
7 11 Class_11 7 1.000 Seven 1 7
8 12 Class_12 2 0.571 Two 1 8
9 12 Class_12 8 0.289 Eight 2 9
10 12 Class_12 1 0.140 One 3 10
11 13 Class_13 8 0.581 Eight 1 11
12 13 Class_13 4 0.210 Four 2 12
13 13 Class_13 2 0.112 Two 3 13
14 13 Class_13 3 0.079 Three 4 14
15 13 Class_13 5 0.018 Five 5 15')