rggplot2identitygeom-col

Plotting position="identity" geom_col in ggplot2 - some series hiding behind others i.e. not visible


I'm trying to plot an annual time series in bar-chart format.

I have 7 sets of yearly data, and they are in a set order (so, the same dataset has the lowest value each year, and the same dataset is highest value each year)

I can plot it as a line graph and all looks well...

But when I plot it as a stacked bar graph, the draw order is meaning some bars and not visible. I don't for the life of me know how to override this. I've tried factor and levels and can't crack it.

If I plot as position="dodge" I can see that the earlier few in the group are smaller, so they are the ones that are 'behind' (i.e. invisible) when I use position="identity".

Is there a way of sorting large to small when plotting position="identity" ?

This code creates a similar dataframe to the first few lines of mine:

temp2 <- as.data.frame(matrix(1:70, 5, 14))
colnames(temp2) <- c("FY", "B", "L1", "L2", "L3", "L4", "M1", "M2", "M3", "M4", 
                     "H1", "H2", "H3", "H4")
temp2$FY <- 1976:1980
temp2$B <- c(800, 935, 650, 850, 650)
temp2$L1 <- temp2$B * 1.0149
temp2$L2 <- temp2$B * 1.0161
temp2$L3 <- temp2$B * 1.0191
temp2$L4 <- temp2$B * 1.0269
temp2$H1 <- temp2$B * 0.9323
temp2$H2 <- temp2$B * 0.9269
temp2$H3 <- temp2$B * 0.9135
temp2$H4 <- temp2$B * 0.8787
temp2$M1 <- temp2$B * 0.9867
temp2$M2 <- temp2$B * 0.9856
temp2$M3 <- temp2$B * 0.9827
temp2$M4 <- temp2$B * 0.9754
temp2 <- gather(temp2, Type, Rain, 
               B:H4, factor_key=TRUE)
temp2 <- ddply(temp2, .(FY, Type), summarise,
               Rain = sum(Rain, na.rm=TRUE))

Then if i do:

ggplot(temp2, aes(x=FY, y=Rain, colour=Type)) + geom_line()

... I get a normal line graph where you can see all the series. But, if i do:

ggplot(temp2, aes(x=FY, y=Rain, fill=Type)) + geom_col(position="identity")

... then some of the bars are hidden behind the other bars.

ggplot(temp2, aes(x=FY, y=Rain, fill=Type)) + geom_col(position="dodge")

... shows that the 2nd 3rd 4th and 5th bars are routinely higher than the first, but the last 8 are lower. I need to somehow reorder my data by sorting it by the value in "Type" to this predefined order I have worked out from a different dataframe.

Hope that is clear.

Edit: (this is using my full dataset but hopefully you get the gist) position="dodge"

Its clear that there are 7 series per "bundle".

But in position="identity" only 5 show up. Something about the outline of each graph maybe interfering with the very small difference between series? position="identity"


Solution

  • You can use forcats::fct_reorder() to order values by Rain. This only works where Type values are in the same relative order in Year. This can best be seen in the following dodged graph.

    library(ggplot2)
    library(plyr)
    library(tidyr)
    library(forcats)
    
    ggplot(temp2, aes(x = FY, y = Rain,
                      fill = fct_reorder(Type, Rain),
                      colour = fct_reorder(Type, Rain))) + 
      geom_col(position="identity")
    

    enter image description here

    
    ggplot(temp2, aes(x = FY, y = Rain, fill = fct_reorder(Type, Rain))) + 
      geom_col(position="dodge")
    

    Created on 2022-05-09 by the reprex package (v2.0.1)