Search code examples
rbar-chartstackedstacked-chart

different colors for each bar in stacked bar graph - base graphics


I want to plot a stacked bar graph like the one attached, but I want the colors to vary between the categories aa, bb and cc. Specifically, I want the grey blocks in bb to be red and the grey blocks in cc to be green. The following code serves as a simple example and illustrates what I have already tried:

aa=c(0.2,0.6,0.1,0.1)
bb=c(0.4,0.5,0.05,0.05)
cc=c(0.5,0.25,0.1,0.15)
x=cbind(aa,bb,cc)
x #the data
aa   bb   cc

[1,] 0.2 0.40 0.50
[2,] 0.6 0.50 0.25
[3,] 0.1 0.05 0.10
[4,] 0.1 0.05 0.15

default behavior, all blocks have the same color in each categories

col=rep(c("white","grey"),2)
col
# [1] "white" "grey"  "white" "grey" 

barplot(x,col=col)

but I want the grey blocks in bb to be red and the grey blocks in cc to be green

col=cbind(rep(c("white","grey"),2),rep(c("white","red"),2),rep(c("white","green"),2))
col

[,1]    [,2]    [,3]   
[1,] "white" "white" "white"
[2,] "grey"  "red"   "green"
[3,] "white" "white" "white"
[4,] "grey"  "red"   "green"

barplot(x,col=col) #not working

col=c(rep(c("white","grey"),2),rep(c("white","red"),2),rep(c("white","green"),2))
col
[1] "white" "grey"  "white" "grey"  "white" "red"   "white" "red"   "white" "green" "white" "green"

barplot(x,col=col) #not working either

Many thanks for any suggestions.

example graph


Solution

  • A workaround: extend your matrix so that values correspond to fictitious categories, with just one color per category. Only one of aa, bb and cc will actually have data in those categories.

    xx <- rep(0,4)
    x <- matrix(c(aa,xx,xx,xx,bb,xx,xx,xx,cc),ncol=3)
    x
          [,1] [,2] [,3]
     [1,]  0.2 0.00 0.00
     [2,]  0.6 0.00 0.00
     [3,]  0.1 0.00 0.00
     [4,]  0.1 0.00 0.00
     [5,]  0.0 0.40 0.00
     [6,]  0.0 0.50 0.00
     [7,]  0.0 0.05 0.00
     [8,]  0.0 0.05 0.00
     [9,]  0.0 0.00 0.50
    [10,]  0.0 0.00 0.25
    [11,]  0.0 0.00 0.10
    [12,]  0.0 0.00 0.15
    

    And plot as you did:

    col <- c(rep(c("white","grey"),2),rep(c("white","red"),2),rep(c("white","green"),2))
    barplot(x,col=col)
    

    enter image description here