Search code examples
rbar-chartoverlap

How to make an overlapping barplot?


Making a barplot the 'standard' way

dat <- read.table(text = "A   B 
+ 1 1 4
+ 2 2 3
+ 3 3 2
+ 4 4 1", header = TRUE)
barplot(as.matrix(dat))

gives a barplot like this:

enter image description here

Instead, I would like to have the different segnments to overlap, like so

enter image description here

How can I make such a plot in R?


Solution

  • There are two ways I have used:

    library('ggplot2')
    counts <- with(diamonds, table(cut, clarity))
    #            clarity
    # cut           I1  SI2  SI1  VS2  VS1 VVS2 VVS1   IF
    # Fair         210  466  408  261  170   69   17    9
    # Good          96 1081 1560  978  648  286  186   71
    # Very Good     84 2100 3240 2591 1775 1235  789  268
    # Premium      205 2949 3575 3357 1989  870  616  230
    # Ideal        146 2598 4282 5071 3589 2606 2047 1212
    

    It is painfully easy in ggplot

    ggplot(diamonds, aes(clarity, fill = cut)) + 
      geom_bar(position = 'identity', alpha = 0.3)
    

    enter image description here

    In base R

    cols <- ggcols(nrow(counts))
    
    for (ii in 1:nrow(counts))
      barplot(counts[ii, ], add = ii != 1, ylim = c(0, 5000),
              col = adjustcolor(cols[ii], 0.3),
              axes = FALSE, axisnames = FALSE, border = NA)
    
    axis(1, barplot(counts, plot = FALSE), colnames(counts))
    axis(2, las = 1)
    title(main = 'identity')
    box(bty = 'l')
    
    legend('topright', bty = 'n', title = 'cut',
           legend = rownames(counts), fill = adjustcolor(cols, 0.5))
    

    enter image description here

    And to match the ggplot colors:

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