rggplot2legendgeom-barstacked-bar-chart

How to split two geom_bar in two separate legends?


What I am trying to do here is to get a stacked bar plot which is working as expected except for the fact that I would like to have two separate legends, one for each set of stacked bars.

In other words, I need a legend for each bar representing my_reorganised_data and p_bars, respectively. If you look at the plot you will notice two sets of labels. the n_1 to n_26 and the other with different names. Well, they should be split in two different legends.

Of course I did some research and I found this question that should be the actual solution, except that it does not work. Or, if it does, I fail to see why it does not work for me. I also tried to do what it is said in this other question but 1. it is not what I want (it's not the optimal solution but it can be a start) and 2. it is not working.

So said, my question still stands. How do I show two different legends?

#load libraries
library("ggplot2")
library("dplyr")
library("viridis")

# load data
my_data <- structure(list(Treatment = c("cat_one", "cat_one", "cat_one", 
"cat_one", "cat_one", "cat_one", "cat_two", "cat_two", "cat_two", 
"cat_two", "cat_two", "cat_two", "cat_one", "cat_two", "cat_one", 
"cat_one", "cat_one", "cat_one", "cat_one", "cat_one", "cat_two", 
"cat_two", "cat_two", "cat_two", "cat_two", "cat_two", "cat_one", 
"cat_two", "cat_one", "cat_two", "cat_one", "cat_two", "cat_one", 
"cat_one", "cat_one", "cat_two", "cat_two", "cat_two", "cat_one", 
"cat_two", "cat_two", "cat_one", "cat_two", "cat_one", "cat_one", 
"cat_one", "cat_one", "cat_one", "cat_one", "cat_one", "cat_two", 
"cat_two", "cat_two", "cat_two", "cat_two", "cat_two", "cat_one", 
"cat_two", "cat_one", "cat_one", "cat_one", "cat_one", "cat_one", 
"cat_one", "cat_two", "cat_two", "cat_two", "cat_two", "cat_two", 
"cat_two", "cat_one", "cat_two", "cat_one", "cat_two", "cat_two", 
"cat_one", "cat_two", "cat_one", "cat_one", "cat_one", "cat_one", 
"cat_two", "cat_two", "cat_two", "cat_one", "cat_two", "cat_one", 
"cat_two", "cat_one", "cat_one", "cat_one", "cat_one", "cat_one", 
"cat_one", "cat_two", "cat_two", "cat_two", "cat_two", "cat_two", 
"cat_two", "cat_one", "cat_two", "cat_one", "cat_one", "cat_one", 
"cat_one", "cat_one", "cat_one", "cat_two", "cat_two", "cat_two", 
"cat_two", "cat_two", "cat_two", "cat_one", "cat_two", "cat_one", 
"cat_one", "cat_two", "cat_two", "cat_one", "cat_two", "cat_one", 
"cat_one", "cat_one", "cat_two", "cat_two", "cat_two", "cat_one", 
"cat_two", "cat_one", "cat_two"), P_level = c("AAA", "AAA", 
"AAA", "AAA", "AAA", "AAA", "AAA", 
"AAA", "AAA", "AAA", "AAA", "AAA", 
"AAA", "AAA", "BBB", "BBB", 
"BBB", "BBB", "BBB", "BBB", 
"BBB", "BBB", "BBB", "BBB", 
"BBB", "BBB", "BBB", "BBB", 
"CCC", "CCC", "MMM", "MMM", 
"UUU", "UUU", "UUU", "UUU", 
"UUU", "UUU", "OOO", "OOO", "RRR", 
"III", "III", "ZZZ", "AAA", 
"AAA", "AAA", "AAA", "AAA", "AAA", 
"AAA", "AAA", "AAA", "AAA", "AAA", 
"AAA", "AAA", "AAA", "BBB", "BBB", 
"BBB", "BBB", "BBB", "BBB", 
"BBB", "BBB", "BBB", "BBB", 
"BBB", "BBB", "BBB", "BBB", 
"CCC", "CCC", "NNN", "MMM", 
"MMM", "UUU", "UUU", "UUU", 
"UUU", "UUU", "UUU", "UUU", 
"OOO", "OOO", "III", "III", "AAA", 
"AAA", "AAA", "AAA", "AAA", "AAA", 
"AAA", "AAA", "AAA", "AAA", "AAA", 
"AAA", "AAA", "AAA", "BBB", "BBB", 
"BBB", "BBB", "BBB", "BBB", 
"BBB", "BBB", "BBB", "BBB", 
"BBB", "BBB", "BBB", "BBB", 
"CCC", "CCC", "CCC", "CCC", 
"MMM", "MMM", "UUU", "UUU", 
"UUU", "UUU", "UUU", "UUU", 
"OOO", "OOO", "III", "III"), T_level = structure(c(1L, 
2L, 3L, 4L, 5L, 9L, 1L, 2L, 3L, 6L, 7L, 9L, 10L, 10L, 11L, 12L, 
13L, 14L, 15L, 19L, 11L, 12L, 14L, 13L, 16L, 19L, 20L, 20L, 21L, 
21L, 23L, 23L, 24L, 25L, 26L, 24L, 25L, 26L, 28L, 28L, 29L, 30L, 
30L, 31L, 1L, 3L, 2L, 5L, 6L, 9L, 1L, 3L, 2L, 6L, 5L, 9L, 10L, 
10L, 11L, 12L, 14L, 17L, 18L, 19L, 11L, 12L, 14L, 13L, 17L, 19L, 
20L, 20L, 21L, 21L, 32L, 23L, 23L, 24L, 25L, 27L, 26L, 24L, 25L, 
26L, 28L, 28L, 30L, 30L, 1L, 2L, 3L, 6L, 8L, 9L, 2L, 1L, 3L, 
6L, 5L, 9L, 10L, 10L, 11L, 12L, 14L, 17L, 16L, 19L, 11L, 12L, 
14L, 13L, 17L, 19L, 20L, 20L, 21L, 22L, 21L, 22L, 23L, 23L, 24L, 
25L, 26L, 24L, 25L, 26L, 28L, 28L, 30L, 30L), levels = c("n_1", 
"n_2", "n_3", "n_4", "n_5", 
"n_6", "n_7", "n_8", "OOO_AAA", "III_AAA", 
"n_9", "n_10", "n_11", "n_12", "n_13", 
"n_14", "n_15", "n_16", "OOO_BBB", 
"III_BBB", "n_17", "n_18", 
"n_19", "n_20", "n_21", "n_22", "n_23", 
"OOO", "n_24", "III", "n_25", "n_26"
), class = "factor", scores = structure(c(n_1 = 1, n_2 = 1, 
n_3 = 1, n_4 = 1, n_5 = 1, 
n_6 = 1, n_7 = 1, n_9 = 2, n_10 = 2, 
n_11 = 2, n_12 = 2, n_13 = 2, n_14 = 2, 
n_17 = 3, n_19 = 4, n_20 = 5, n_21 = 5, 
n_22 = 5, n_24 = 7, n_25 = 9, n_15 = 2, n_16 = 2, 
n_26 = 10, n_23 = 5, n_8 = 1, n_18 = 3, 
`OOO_AAA` = 1, `III_AAA` = 1, `OOO_BBB` = 2, 
`III_BBB` = 2, OOO = 6, III = 8
), dim = 32L, dimnames = list(c("n_1", "n_2", 
"n_3", "n_4", "n_5", "n_6", 
"n_7", "n_9", "n_10", "n_11", 
"n_12", "n_13", "n_14", "n_17", 
"n_19", "n_20", "n_21", "n_22", "n_24", 
"n_25", "n_15", "n_16", "n_26", 
"n_23", "n_8", "n_18", "OOO_AAA", 
"III_AAA", "OOO_BBB", "III_BBB", 
"OOO", "III")))), Rel_abs = c(0.197236525537948, 
0.18059182696185, 0.0960061235433623, 0.0314376978000554, 0.0303295252226453, 
0.0818921203233927, 0.153370540183451, 0.149337024031343, 0.0911456587080675, 
0.0445729227578018, 0.0115423916050278, 0.029107556287552, 0.0717485171783193, 
0.0613101713199937, 0.0837942231333853, 0.0722583983539544, 0.0314681621541614, 
0.0171399554267858, 0.00635616813927082, 0.0124363457937222, 
0.139917552162451, 0.114506605930535, 0.0449842607739858, 0.00976343619158412, 
0.00254691083525256, 0.00654796605297846, 0.00220019596740987, 
0.00194899748305013, 5.73368194119536e-05, 0.000132332244746293, 
0.0364601165426766, 0.0193592404961568, 0.00156357871594744, 
0.000764522998609061, 0, 0.00246613109745212, 0.000638157950560195, 
4.19385941367744e-05, 0, 2.57925788421046e-05, 2.13196887325445e-05, 
0.04624323871105, 0.1167130930263, 1.54206760424377e-05, 0.232693154176897, 
0.180512037382935, 0.158005200574839, 0.026994062605453, 0.0261692942618925, 
0.0455221879962145, 0.177017047627869, 0.144435394974196, 0.136525448031613, 
0.0325649066436204, 0.0171620065921757, 0.0466744029752315, 0.0620181420158349, 
0.0620225711139161, 0.1210034228649, 0.0543056593550518, 0.0138567098789763, 
0.00540081815749568, 0.00259410669048289, 0.0072679056122694, 
0.109151912074479, 0.0822151962914109, 0.0577327362042143, 0.0124137485500088, 
0.0109089377474518, 0.0173892286380589, 0.00187308409301566, 
0.00167892918071478, 0.000229495548816174, 7.05755928177126e-05, 
1.22810895782674e-05, 0.0146041879196967, 0.00897959698744225, 
0.00179123920931847, 0.000981587422490768, 1.59337157425112e-05, 
0, 0.00202319569102623, 0.000992843033225235, 5.93289609573076e-05, 
0, 0, 0.0441617705176784, 0.0799697119999939, 0.196598237823455, 
0.192793722723506, 0.0890656734404445, 0.0466312053179004, 0.0317971328246452, 
0.0530252037618935, 0.221624497118494, 0.180792630753154, 0.0905991978561714, 
0.0290273088902963, 0.0124423966658422, 0.0207941981068082, 0.0546823215462327, 
0.0899908289755282, 0.117052149010945, 0.0504780268348555, 0.0284605842644161, 
0.0132635813526369, 0.00721150571853264, 0.012853529794774, 0.101891170880455, 
0.0581807288694833, 0.0225257822875979, 0.0162876640471769, 0.00854280683294597, 
0.0146315113635556, 0.00189102136915801, 0.00338046959383979, 
6.72270846485766e-05, 0, 7.44062219715483e-05, 5.16115713142887e-05, 
0.039029154441234, 0.0167687343877863, 0.00373031306151622, 0.00166279237706458, 
1.81771912604064e-05, 0.00411965195196075, 0.00360601655443808, 
4.71400881175341e-05, 0, 5.93183139362447e-06, 0.059688440060881, 
0.104615315151669), timepoint = structure(c(1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L), levels = c("time_one", 
"time_two", "time_three"), class = "factor")), row.names = c("1", "2", "3", "4", "5", "6", 
"14", "15", "16", "17", "18", "19", "39", "41", "7", "8", "9", 
"10", "11", "12", "20", "21", "22", "23", "24", "25", "40", "42", 
"29", "35", "13", "26", "27", "28", "31", "33", "34", "36", "32", 
"38", "37", "43", "44", "30", "110", "210", "310", "45", "51", 
"61", "141", "151", "161", "171", "181", "191", "391", "411", 
"71", "81", "91", "101", "111", "121", "201", "211", "221", "231", 
"241", "251", "401", "421", "291", "351", "371", "131", "261", 
"271", "281", "301", "311", "331", "341", "361", "321", "381", 
"431", "441", "112", "212", "312", "46", "52", "62", "142", "152", 
"162", "172", "182", "192", "392", "412", "72", "82", "92", "102", 
"113", "122", "202", "213", "222", "232", "242", "252", "402", 
"422", "292", "313", "352", "362", "132", "262", "272", "282", 
"302", "332", "342", "372", "322", "382", "432", "442"), class = "data.frame")

# set levels for T_level
last_two <- as.character(c(my_data$T_level[!grepl("OOO|III", my_data$T_level)], my_data$T_level[grepl("OOO|III", my_data$T_level)]))
my_data$T_level <- factor(my_data$T_level, levels=unique(last_two))

# set levels for timepoint
my_data$timepoint <- factor(my_data$timepoint, levels=c("time_one", "time_two", "time_three"))

# reorder T_level by P_level. to to it, create a numeric
# ordering variable using P_level
my_data$sort_by_phyl <- as.numeric(factor(my_data$P_level, levels=unique(my_data$P_level)))
# apply the reordering
my_data$T_level <- reorder(my_data$T_level, my_data$sort_by_phyl)
# apply namer to the reordering factor variable
names(my_data$sort_by_phyl) <- my_data$P_level
    
# create P_level bars   
p_bars <- my_data %>% group_by(Treatment, timepoint, P_level) %>% summarize(Rel_abs=sum(Rel_abs))

# set position for the P_level bars
p_bars$x <- ifelse(p_bars$Treatment=="cat_one", 1.5, 2.5)
p_bars$P_level <- factor(p_bars$P_level, unique(my_data$P_level[match(levels(my_data$T_level), my_data$T_level)]))

# reorganise data for plotting purposes
my_reorganised_data <- my_data %>% count(T_level, Treatment, timepoint, wt=Rel_abs, name="Rel_abs")

# get the plot ready
the_plot <- ggplot() +
        geom_bar(data=my_reorganised_data, aes(fill=T_level, y=Rel_abs, x=Treatment), position="fill", stat="identity", color="black", width=0.5) +
        geom_bar(data=p_bars, aes(x=x, y=Rel_abs/sum(Rel_abs), fill=P_level), stat="identity", position="fill", color="black", width=0.15) +
        scale_fill_viridis(discrete=T, option="turbo") +
        theme_bw() +
        xlab("") +
        ylab("") +
        ylim(0, 1) +
        facet_wrap(~timepoint) +
        labs(fill="legend") +
        theme(text=element_text(size=25, face="bold"), legend.position="right", legend.text=element_text(size=15), legend.key.height=unit(0.7,'cm')) +
        guides(fill=guide_legend(ncol=2))
# print
print(the_plot)

Solution

  • One option to get separate legends would be to use the ggnewscale package which allows for multiple scales and legends for the same aesthetic. In the code below I use the same color palettes but of course could you customize the palettes to your liking:

    library(ggplot2)
    library(ggnewscale)
    
    ggplot() +
      geom_bar(
        data = my_reorganised_data, aes(fill = T_level, y = Rel_abs, x = Treatment),
        position = "fill", stat = "identity", color = "black", width = 0.5
      ) +
      scale_fill_viridis_d(option = "turbo", name = "T_level") +
      ggnewscale::new_scale_fill() +
      geom_bar(
        data = p_bars, aes(x = x, y = Rel_abs / sum(Rel_abs), fill = P_level),
        stat = "identity", position = "fill", color = "black", width = 0.15
      ) +
      scale_fill_viridis_d(option = "turbo", name = "P_bars") +
      theme_bw() +
      labs(x = NULL, y = NULL) +
      ylim(0, 1) +
      facet_wrap(~timepoint) +
      theme(
        text = element_text(size = 25, face = "bold"), legend.position = "right",
        legend.text = element_text(size = 15), legend.key.height = unit(0.7, "cm")
      ) +
      guides(fill = guide_legend(ncol = 2))
    

    enter image description here