2

I would like to create a stacked barplot with three different legends for different groupings of data.

For example, given the following dataframe:

Year <- as.factor(c(rep(1, 10), rep(2, 10), rep(3,10), rep(4,10), rep(5,10), rep(6,10)))
Category <- as.factor(c(rep("a", 15), rep("b", 10), rep("c", 10), rep("d",10), rep("e", 10), rep("f", 5)))
Region <- as.factor(c(rep("region1", 25), rep("region2", 20), rep("region3",15)))
data <- data.frame(Year, Category, Region)

I would like to plot a stacked barplot of the count of each Category by year.

ggplot() + geom_bar(data=data,aes(x=Year, fill=Category)) 

However, instead of having one legend for Category (like above) I would like to have three legends with Category subset by Region (ie the legend titled "region1" would show Categories "a" and "b"; the legend titled "region2" would show Categories "c" and "d"; and the legend titled "region3" would show Categories "e" and "f".

I have tried referring to these two threads: Legends for multiple fills in ggplot and R: Custom Legend for Multiple Layer ggplot. However, I have had no luck applying them to a barplot. Any help would be greatly appreciated!

zx8754
  • 52,746
  • 12
  • 114
  • 209
Powege
  • 685
  • 5
  • 12

2 Answers2

0

What about something like that:

ggplot() + geom_bar(data=data,aes(x=Year, fill=Category, color=Region)) + scale_fill_brewer(palette="Greens") + scale_color_manual(values = c("red", "black", "grey"))

with scale_color_manual to be customized. You can get inspired by http://colorbrewer2.org/#type=sequential&scheme=BuGn&n=3

valz
  • 36
  • 3
0

You can sometimes do this sort of thing the "hard" way by mapping layers to additional aesthetics and then using override.aes to make the legends based on those aesthetics look the way you want them to. It's not pretty.

Here is an example, where the fill legend is suppressed and legends are made for the three "region" subsets via color, size, and alpha.

First, get the ggplot2 colors for 6 colors as shown here.

gg_color_hue = function(n) {
    hues = seq(15, 375, length = n + 1)
    hcl(h = hues, l = 65, c = 100)[1:n]
}

cols = gg_color_hue(6)

The three extraneous geom_point layers are included only to add the three legends to the plot; the actual points are suppressed by setting the size to 0 or color to NA.

Then comes the messy work in guide_legend, where each legend is changed to show the correct colors based on cols above. Legends names are changed and the legend order is set.

ggplot(data = data, aes(x = Year) ) +
    geom_bar( aes(fill = Category), show.legend = FALSE ) +
    geom_point(data = subset(data, Category %in% c("a", "b") ),
               aes(color = Category), stat = "count", size = 0) +
    geom_point(data = subset(data, Category %in% c("c", "d") ),
               aes(size = Category), stat = "count", color = NA) +
    geom_point(data = subset(data, Category %in% c("e", "f") ),
               aes(alpha = Category), stat = "count", size = 0) +
    guides(color = guide_legend(title = "Region 1", order = 1, 
                                override.aes = list(shape = 15, size = 5, color = cols[1:2]) ),
           size = guide_legend(title = "Region 2", order = 2, 
                                override.aes = list(shape = 15, size = 5, color = cols[3:4]) ),
           alpha = guide_legend(title = "Region 3", order = 3, 
                                override.aes = list(shape = 15, size = 5, color = cols[5:6], alpha = 1) ) ) +
    theme(legend.key = element_rect(fill = "white") )

enter image description here

aosmith
  • 34,856
  • 9
  • 84
  • 118