Change colours of particular bars in a bar chart

后端 未结 4 1063
轮回少年
轮回少年 2020-12-01 04:47

I\'ve been creating some bar-charts and I was wondering is it possible to colour bars on a chart depending on whether they lie above or below the x-axis?

For clarifi

相关标签:
4条回答
  • 2020-12-01 05:09

    I found this page while looking for help on how to colour individual bars in a bar chart according to a factor. I couldn't find any other source of information but thanks to this page, came up with this:

    cols <- ifelse(df$Country == "Greenland", "green","blue")

    It then gets passed into barplot in the usual way as described above:

    barplot(x, col = cols)

    0 讨论(0)
  • 2020-12-01 05:17

    A ggplot2 solution using geom_bar with stat_identity.

    library(ggplot2)
    ggplot(dat, aes(x= seq_along(x), y = x)) + 
      geom_bar(stat = 'identity', aes(fill = x>0), position = 'dodge', col = 'transparent') + 
      theme_bw() + scale_fill_discrete(guide = 'none') + 
      labs(x = '', y = 'NAO Index')
    

    enter image description here

    scale_fill_discrete(guide = 'none') removes the legend, position = 'dodge' stops the warning that comes from the default position = 'stack'.

    0 讨论(0)
  • 2020-12-01 05:18

    One way is to index a vector of colours with a logical or factor variable (this is a common idiom in R.

    set.seed(1)
    NAO <- rnorm(40)
    cols <- c("red","black")
    pos <- NAO >= 0
    barplot(NAO, col = cols[pos + 1], border = cols[pos + 1])
    

    The trick here is pos:

    > pos
     [1] FALSE  TRUE FALSE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE FALSE
    [11]  TRUE  TRUE FALSE FALSE  TRUE FALSE FALSE  TRUE  TRUE  TRUE
    [21]  TRUE  TRUE  TRUE FALSE  TRUE FALSE FALSE FALSE FALSE  TRUE
    [31]  TRUE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE
    

    which we coerce to numeric in the barplot() call:

    > pos + 1
     [1] 1 2 1 2 2 1 2 2 2 1 2 2 1 1 2 1 1 2 2 2 2 2 2 1 2 1 1 1 1 2
    [31] 2 1 2 1 1 1 1 1 2 2
    

    The vector of 1s and 2s selects elements from the vector of colour cols, such that:

    > cols[pos + 1]
     [1] "red"   "black" "red"   "black" "black" "red"   "black"
     [8] "black" "black" "red"   "black" "black" "red"   "red"  
    [15] "black" "red"   "red"   "black" "black" "black" "black"
    [22] "black" "black" "red"   "black" "red"   "red"   "red"  
    [29] "red"   "black" "black" "red"   "black" "red"   "red"  
    [36] "red"   "red"   "red"   "black" "black"
    

    which is the colour passed on to each bar drawn.

    In the code above I also set the border of the bars to the relevant colour, via argument border.

    The resulting plot should look like this

    enter image description here

    0 讨论(0)
  • Here's one strategy:

    ## Create a reproducible example
    set.seed(5)
    x <- cumsum(rnorm(50))
    
    ## Create a vector of colors selected based on whether x is <0 or >0  
    ## (FALSE + 1 -> 1 -> "blue";    TRUE + 1 -> 2 -> "red")
    cols <- c("blue", "red")[(x > 0) + 1]  
    
    ## Pass the colors in to barplot()   
    barplot(x, col = cols)
    

    If you want more than two value-based colors, you can employ a similar strategy (using findInterval() in place of the simple logical test):

    vals <- -4:4
    breaks <- c(-Inf, -2, 2, Inf)
    c("blue", "grey", "red")[findInterval(vals, vec=breaks)]
    # [1] "blue" "blue" "grey" "grey" "grey" "grey" "red"  "red"  "red" 
    

    enter image description here

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