How to make an overlapping barplot?

前端 未结 2 588
有刺的猬
有刺的猬 2020-12-17 01:39

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))
<         


        
相关标签:
2条回答
  • 2020-12-17 02:20

    There are two ways I have used:

    (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

    library(ggplot2)
    ggplot(diamonds, aes(clarity, fill = cut)) + 
      geom_bar(position = 'identity', alpha = .3)
    

    enter image description here

    In base R

    par(xpd = TRUE, mar = c(4,4,2,2))
    invisible(sapply(1:nrow(counts), function(x)
      barplot(counts[x, ], axes = FALSE, axisnames = FALSE,
              main = 'identity', border = NA,
              col = tcol(ggcols(5)[x], 50), 
              axis.lty = 1, ylim = c(0, 5000), 
              add  = ifelse(x == 1, FALSE, TRUE))))
    axis(1, at = barplot(counts, plot = FALSE), labels = colnames(counts))
    axis(2, at = seq(0, 5000, 1000), labels = seq(0, 5000, 1000))
    legend('topright', bty = 'n', title = 'cut',
           legend = rownames(counts), fill = tcol(ggcols(5), 100))
    

    enter image description here

    I used this transparent color function from a personal package:

    #' Transparent colors
    #' 
    #' Add transparency to colors
    #' 
    #' @usage tcol(color, trans = 255)
    #' 
    #' @param color single or string of color names (or hexadecimal format) 
    #' @param trans transparency defined as an integer in the range 
    #' \code{[0, 255]} where \code{0} is fully transparent and \code{255} is fully
    #' visible; see details
    #' 
    #' @details This is a vectorized function to add transparency to colors. 
    #' \code{color} and \code{trans} must either be the same length or one of the 
    #' two must have length one. 
    #' 
    #' The function adds integers (in hex) between 0 (fully transparent) and 255
    #' (fully visible) to the color(s) given. \code{color} values are converted to
    #' RGB with transparency.
    #' 
    #' @seealso \code{\link{num2hex}}, \code{\link{col2rgb}}
    #' 
    #' @examples
    #' cols <- c('red','green','pink')
    #' 
    #' # a normal plot
    #' plot(rnorm(100), col = tcol(cols), pch = 16, cex = 4)
    #' 
    #' # more transparent
    #' plot(rnorm(100), col = tcol(cols, 100), pch = 16, cex = 4)
    #' 
    #' # hexadecimal colors also work
    #' cols <- c('#FF0000','#00FF00','#FFC0CB')
    #' plot(rnorm(100), col = tcol(cols, 200), pch= 16, cex = 4)
    #' @export
    
    tcol <- function(color, trans = 255) {
    
      if (length(color) != length(trans) & 
            !any(c(length(color), length(trans)) == 1)) 
        stop('Vector lengths not correct')
      if (length(color) == 1 & length(trans) > 1) 
        color <- rep(color, length(trans))
      if (length(trans) == 1 & length(color) > 1) 
        trans <- rep(trans, length(color))
    
      res <- paste0('#', apply(apply(rbind(col2rgb(color)), 2, function(x) 
        format(as.hexmode(x), 2)), 2, paste, collapse = ''))
      res <- unlist(unname(Map(paste0, res, as.character(as.hexmode(trans)))))
      res[is.na(color)] <- NA
      return(res)
    }
    

    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]
    }
    
    0 讨论(0)
  • 2020-12-17 02:23

    In plain R overlapping bar plots can also be achieved by :

    1 - making bars transparent using the alpha value of the rgb function call (e.g., rgb(redValue, greenValue, blueValue, alphaLevel) by which rgb(1, 0, 0, .5) corresponds to red with an alpha level of .5)

    2 - adding different bar plots on top of each other using the option add=TRUE in the call to barplot Or in code:

    dat <- read.table(text = "A   B
      1 4
      2 3
      3 2
      4 1", header = TRUE)
    
    barplot(dat$A, col=rgb(1, 0, 0, .5)) 
    barplot(dat$B, col=rgb(0, 1, 0, .5), add=TRUE) 
    
    # adding a legend
    legend('top', bty = 'n', title = 'Legend',
      legend = c('A', 'B'), fill = c('red', 'green'))
    

    The plot can be further prettified, but I believed this code provides a very simple alternative which would do the trick.

    0 讨论(0)
提交回复
热议问题