2

I have successfully created a stacked bar plot but I cannot add labels indicating the percentages. That is all that I am missing. I basically do not know how to use the geom_label/geom_text correctly, I have tried many many solutions but nothing has worked for me.

enter image description here

I have tried the geom_text function but it keeps telling me I am doing it wrong.

year Month2 Month Day HE Supply MUnit    MPrice MBlock Fuel
2017    1   Jan   01    8   9408    SD2  15.38  126   COAL
2017    1   Jan   01    9   9388    SD3  15.46  218   COAL
2017    1   Jan   01    10  9393    SD3  15.46  218   COAL
2017    1   Jan   01    11  9628    SD4  15.47  203   COAL
2017    1   Jan   01    12  9943    EGC1 21.40  72    GAS
2017    1   Jan   01    13  10106   BR5  21.41  245   COAL
2017    1   Jan   01    14  10114   BR5  21.41  245   COAL
2017    1   Jan   01    15  9971    EGC1 20.75  75    GAS
2017    1   Jan   01    16  10302   BR5  21.41  245   COAL
2017    1   Jan   01    17  10655   TC01 22.77  11    GAS
2017    1   Jan   01    18  10811   CAL1 24.88  25    GAS
2017    1   Jan   01    19  10821   CAL1 24.88  25    GAS
2017    1   Jan   01    20  10765   BIG  26.00  30    HYDRO
2017    1   Jan   02    8   10428   CAL1 22.04  30    GAS
2017    1   Jan   02    9   10723   CAL1 29.97  59    GAS
2017    1   Jan   02    10  10933   BRA  44.50  30    HYDRO
2017    1   Jan   02    11  11107   ANC1 46.46  63    GAS
2017    1   Jan   02    12  11098   ANC1 46.46  38    GAS
2017    1   Jan   02    13  10839   JOF1 26.59  45    GAS
2017    1   Jan   02    14  10814   JOF1 26.09  15    GAS
2017    1   Jan   02    15  10797   BIG  26.00  30    HYDRO

sp <- ggplot(data = MU17) +      
       geom_bar(mapping = aes(x = factor(Month,levels=month.abb),
                fill = factor(Fuel, levels=c("COAL", "GAS","HYDRO","BIOMASS"))),
                position = "Fill") +
       scale_y_continuous(labels = scales::percent) 


sp + scale_fill_manual(breaks=c("COAL", "GAS","HYDRO","BIOMASS"), 
                      values=c("black","yellow","blue","green")) + 
     labs(x = "2017" , y="Marginal Fuel Between HE8 & HE20") + 
     labs(fill="Fuel Type")

I am hoping to get the exact same plot that I get, just with labels indicating percentages.

VicWatt
  • 31
  • 2
  • 1
    you need to share some of your data. read here to learn how: https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example – M-- Jun 11 '19 at 20:11
  • 2
    Did you try the answers at [this SO question](https://stackoverflow.com/questions/6644997/showing-data-values-on-stacked-bar-chart-in-ggplot2)? If one of those didn't work, add the code you tried along with your example data so folks can see where things might have gone wrong. – aosmith Jun 11 '19 at 20:34
  • 1
    Or [this one](https://stackoverflow.com/questions/56485047/position-argument-of-geom-text-to-set-different-tags/56485465#56485465)? Your question seems a lot like a duplicate. – Rui Barradas Jun 11 '19 at 20:37
  • 1
    @aosmith, Yes, I have tried those. Basically every solution I have tried gives me the same message: Error: geom_text requires the following missing aesthetics: x, y. I'm just trying to teach myself R, for the most part I have been able to figure things out alone, though I have been stuck with this for almost 2 weeks now. – VicWatt Jun 11 '19 at 20:48
  • It's helpful to show an attempt so we can address what you're actually doing wrong rather than just show you a working solution. From the error message you mention in comments, I think the problem is that you're specifying `aes()` in the `geom_bar()` layer, so it is local to that layer and not inherited by the geom text layer. If you put your `aes()` argument inside `ggplot()` instead of inside `geom_bar()`, you should be able to get the other solutions to work. – Gregor Thomas Jun 11 '19 at 20:59
  • The error comes from the place where you define the aesthetics. It's a frequent error **not to define them in the initial call to `ggplot`**. Try moving `aes(x = etc)` from `geom_bar` to `ggplot()`. – Rui Barradas Jun 11 '19 at 20:59
  • Also, I would use `geom_label` to have a background of a different color, since the bars colors are so dark. – Rui Barradas Jun 11 '19 at 21:00
  • One of the real complications here is that you are trying to have ggplot2 calculate the labels for you (as it calculated the bars for you). I think the most straightforward thing to do is to calculate the percentage of `Fuel` for each `Month` outside of **ggplot2** and then make the plot using that `y` value. If you do this you can use an approach much more similar to the linked answers. – aosmith Jun 11 '19 at 21:41
  • Right on. Thank you guys , I really appreciate your help. – VicWatt Jun 11 '19 at 21:56

1 Answers1

0

I personally prefer using geom_col over geom_bar and process the data myself rather than let ggplot2 do it. This way you have more control over whats going on.

Since you have not provided all of you data I just use the snippet you provided.

library(tibble)
MU17 <- tribble(~year, ~Month2, ~Month, ~Day, ~HE, ~Supply, ~MUnit, ~MPrice, ~MBlock, ~Fuel,
                    2017,    1,   "Jan",   01,    8,   9408,    "SD2",  15.38,  126,   "COAL",
                    2017,    1,   "Jan",   01,    9,   9388,    "SD3",  15.46,  218,  "COAL",
                    2017,    1,   "Jan",   01,    10,  9393,    "SD3",  15.46,  218,   "COAL",
                    2017,    1,   "Jan",   01,    11,  9628,    "SD4",  15.47,  203,   "COAL",
                    2017,    1,   "Jan",   01,    12,  9943,    "EGC1", 21.40,  72,    "GAS",
                    2017,    1,   "Jan",   01,    13,  10106,   "BR5",  21.41,  245,   "COAL",
                    2017,    1,   "Jan",   01,    14,  10114,   "BR5",  21.41,  245,   "COAL",
                    2017,    1,   "Jan",   01,    15,  9971,    "EGC1", 20.75,  75,    "GAS",
                    2017,    1,   "Jan",   01,    16,  10302,   "BR5",  21.41,  245,   "COAL",
                    2017,    1,   "Jan",   01,    17,  10655,   "TC01", 22.77,  11,    "GAS",
                    2017,    1,   "Jan",   01,    18,  10811,   "CAL1", 24.88,  25,    "GAS",
                    2017,    1,   "Jan",   01,    19,  10821,   "CAL1", 24.88,  25,    "GAS",
                    2017,    1,   "Jan",   01,    20,  10765,   "BIG",  26.00,  30,    "HYDRO",
                    2017,    1,   "Jan",   02,    8,   10428,   "CAL1", 22.04,  30,    "GAS",
                    2017,    1,   "Jan",   02,    9,   10723,   "CAL1", 29.97,  59,    "GAS",
                    2017,    1,   "Jan",   02,    10,  10933,   "BRA",  44.50,  30,    "HYDRO",
                    2017,    1,   "Jan",   02,    11,  11107,   "ANC1", 46.46,  63,    "GAS",
                    2017,    1,   "Jan",   02,    12,  11098,   "ANC1", 46.46,  38,    "GAS",
                    2017,    1,   "Jan",   02,    13,  10839,   "JOF1", 26.59,  45,    "GAS",
                    2017,    1,   "Jan",   02,    14,  10814,   "JOF1", 26.09,  15,    "HYDRO",
                    2017,    1,   "Jan",   02,    15,  10797,   "BIG",  26.00,  30,    "BIOMASS",

                    2017,    2,   "Feb",   01,    8,   9408,    "SD2",  15.38,  126,   "COAL",
                    2017,    2,   "Feb",   01,    9,   9388,    "SD3",  15.46,  218,  "COAL",
                    2017,    2,   "Feb",   01,    10,  9393,    "SD3",  15.46,  218,   "COAL",
                    2017,    2,   "Feb",   01,    11,  9628,    "SD4",  15.47,  203,   "COAL",
                    2017,    2,   "Feb",   01,    12,  9943,    "EGC1", 21.40,  72,    "GAS",
                    2017,    2,   "Feb",   01,    13,  10106,   "BR5",  21.41,  245,   "COAL",
                    2017,    2,   "Feb",   01,    14,  10114,   "BR5",  21.41,  245,   "COAL",
                    2017,    2,   "Feb",   01,    15,  9971,    "EGC1", 20.75,  75,    "GAS",
                    2017,    2,   "Feb",   01,    16,  10302,   "BR5",  21.41,  245,   "COAL",
                    2017,    2,   "Feb",   01,    17,  10655,   "TC01", 22.77,  11,    "GAS",
                    2017,    2,   "Feb",   01,    18,  10811,   "CAL1", 24.88,  25,    "GAS",
                    2017,    2,   "Feb",   01,    19,  10821,   "CAL1", 24.88,  25,    "GAS",
                    2017,    2,   "Feb",   01,    20,  10765,   "BIG",  26.00,  30,    "HYDRO",
                    2017,    2,   "Feb",   02,    8,   10428,   "CAL1", 22.04,  30,    "GAS",
                    2017,    2,   "Feb",   02,    9,   10723,   "CAL1", 29.97,  59,    "GAS",
                    2017,    2,   "Feb",   02,    10,  10933,   "BRA",  44.50,  30,    "HYDRO",
                    2017,    2,   "Feb",   02,    11,  11107,   "ANC1", 46.46,  63,    "GAS",
                    2017,    2,   "Feb",   02,    12,  11098,   "ANC1", 46.46,  38,    "GAS",
                    2017,    2,   "Feb",   02,    13,  10839,   "JOF1", 26.59,  45,    "GAS",
                    2017,    2,   "Feb",   02,    14,  10814,   "JOF1", 26.09,  15,    "HYDRO",
                    2017,    2,   "Feb",   02,    15,  10797,   "BIG",  26.00,  30,    "BIOMASS"
    )

When doing the processing I calculate:

the number of occurences/observations  (n)
their relative frequency per month (p)
a percent label of p (p2)
the y-position in the bar chart of each label (pos)

This data I pipe into ggplot. Important is that I use geom_col with position = “fill”. Since I provide a positon value pos for geom_text, it is necessary to use position = “identity” here . Further, you need some kind of ifelse-Statement to adjust the colour of geom_text to white #FFFFFF for darker background colors in HYDRO and COAL.

Good luck using this approach on your original data.

library(ggplot2)
library(dplyr)

MU17 %>%
    mutate(Fuel = factor(Fuel), 
           Month = factor(Month,levels = month.abb)) %>% 
    group_by(Month, Month2, Fuel) %>%
    summarise(n = n()) %>%
    group_by(Month) %>%
    mutate(p = n / sum(n),
           p2 = paste(formatC(p*100, digits = 2, format = "fg"),"%",sep = ""),
           pos = cumsum(p) - (0.5 * p)) %>%

    ggplot(aes(x = Month, y = p, fill = factor(Fuel, levels = rev(levels(Fuel))))) +   
    geom_col(width = 0.5, position = "fill") +
    scale_y_continuous(limits = c(0, 1), breaks = c(-.5,-.25,0,.25,.5,.75,1), expand = c(0, 0), 
                       labels = scales::percent) +
    scale_fill_manual(breaks = c("COAL", "GAS","HYDRO","BIOMASS"),
                      values = c("black","yellow","blue","green")) +
    geom_text(aes(label = p2, y = pos),
              position = "identity",
              vjust = 0.5,
              colour = ifelse(data$Fuel == "COAL" | data$Fuel == "HYDRO", "#FFFFFF", "#000000")) + 
    labs(x = "2017" , y = "Marginal Fuel Between HE8 & HE20") +
    labs(fill = "Fuel Type")
TimTeaFan
  • 17,549
  • 4
  • 18
  • 39