【问题标题】:How can I have different color for each bar of stack barplots? in R如何为每个堆栈条形图设置不同的颜色?在 R 中
【发布时间】:2015-06-13 08:28:56
【问题描述】:

我的问题可能很简单,但我找不到答案! 我有一个包含 12 个条目的矩阵,我用 R 中的 barplot 函数制作了一个堆栈 barplot。 使用此代码:

    mydata <- matrix(nrow=2,ncol=6, rbind(sample(1:12, replace=T)))

    barplot(mydata, xlim=c(0,25),horiz=T, 
    legend.text = c("A","B","C","D","E","F"),
col=c("blue","green"),axisnames = T, main="Stack barplot")

这是代码中的图像:

我想做的是给每个组(A:F,只有蓝色部分)一个不同的颜色,但我不能添加两种以上的颜色。

我也想知道如何从 x=2 而不是 0 开始绘图。 我知道可以使用 xlim=c(2,25) 来选择 x 的范围,但是当我选择条形的那部分超出范围时,我会得到这样的图片:

我想要的是忽略小于 2 的条形部分,并从 2 开始 x 轴并显示其余条形,而不是将它们超出范围。

提前谢谢你,

【问题讨论】:

  • 您打算使用barplot 还是愿意接受其他解决方案?
  • 只要我能得到我想要的输出,我愿意接受任何其他选择! :)

标签: r colors stack bar-chart legend


【解决方案1】:

您可以通过使用 barplot() 的“add”和“offset”参数以及设置轴和轴名 FALSE 来避免重复绘图:(我正在投入我的色盲调色板,因为我我是红绿色盲)

# Conservative 8-color palette adapted for color blindness, with first color = "black".
# Wong, Bang. "Points of view: Color blindness." nature methods 8.6 (2011): 441-441.
colorBlind.8 <- c(black="#000000", orange="#E69F00", skyblue="#56B4E9", bluegreen="#009E73",
    yellow="#F0E442", blue="#0072B2", reddish="#D55E00", purplish="#CC79A7")
mydata <- matrix(nrow=2,ncol=6, rbind(sample(1:12, replace=T)))
cols <- colorBlind.8[1:ncol(mydata)]
bar2col <- colorBlind.8[8]
barplot(mydata[1,], xlim=c(0,25), horiz=T, col=cols, axisnames=T,
    legend.text=c("A","B","C","D","E","F"), main="Stack barplot")
barplot(mydata[2,], offset=mydata[1,], add=T, axes=F, axisnames=F, horiz=T, col=bar2col)

对于您问题的第二部分,“偏移”参数也用于第一组条形图,您更改 xlim 并使用 xaxp 调整 x 轴编号,当然您还必须调整高度去除多余的偏移量:

offset <- 2
h <- mydata[1,] - offset
h[h < 0] <- 0
barplot(h, offset=offset, xlim=c(offset,25), xaxp=c(offset,24,11), horiz=T, 
    legend.text=c("A","B","C","D","E","F"),
    col=cols, axisnames=T, main="Stack barplot")
barplot(mydata[2,], offset=offset+h, add=T, axes=F, axisnames=F, horiz=T, col=bar2col)

【讨论】:

    【解决方案2】:

    正如在另一篇文章中已经提到的,完全清楚您想要的输出。这里使用ggplot2 的另一个选项。我认为这里的难点在于 reshape2 数据,那么 plot 步骤就直截了当。

    library(reshape2)
    library(ggplot2)
    
    ## Set a seed to make your data reproducible
    set.seed(1)
    mydata <- matrix(nrow=2,ncol=6, rbind(sample(1:12, replace=T)))
    
    ## tranfsorm you matrix to names data.frame
    myData <- setNames(as.data.frame(mydata),LETTERS[1:6])
    ## put the data in the long format 
    dd <- melt(t(myData))
    ## transform the fill variable to the desired behavior.
    ## I used cumsum to bes sure to have a unique value for all VAR2==2. 
    ## maybe you should chyange this step if you want an alternate behvior 
    ## ( see other solution)
    dd <- transform(dd,Var2 =ifelse(Var2==1,cumsum(Var2)+2,Var2))
    ## a simple bar plot
    ggplot(dd) +
      ## use stat identity since you want to set the y aes
      geom_bar(aes(x=Var1,fill=factor(Var2),y=value),stat='identity') +
      ## horizontal rotation and zooming
      coord_flip(ylim = c(2, max(dd$value)*2)) +
      theme_bw()
    

    使用 lattice 包的另一种选择

    我喜欢lattice 中的公式符号及其翻转坐标的灵活性,例如:

    library(lattice)
    
    barchart(Var1~value,groups=Var2,data=dd,stack=TRUE,
             auto.key = list(space = "right"),
             prepanel = function(x,y, ...) { 
               list(xlim = c(2, 2*max(x, na.rm = TRUE))) 
             })
    

    【讨论】:

    • 太棒了!!用格子改变颜色:barchart(Var1~value,groups=Var2,data=dd,stack=TRUE, auto.key = list(space = "right"),col=dd$Var2), par.settings = simpleTheme(col=dd$Var2), prepanel = function(x,y, ...) { list(xlim = c(2, 2*max(x, na.rm = TRUE))) })
    【解决方案3】:

    我不完全确定这是否是您要查找的内容:“A”有两个值(x1 和 x2),但您的图例似乎暗示了其他情况。

    这是一种使用 ggplot 实现所需内容的方法。首先我们设置data.frame(ggplot需要):

    set.seed(1)
    df <- data.frame(
      name = letters[1:6],
      x1=sample(1:6, replace=T),
                     x2=sample(1:6, replace=T))
    
      name x1 x2
    1    a  5  3
    2    b  3  5
    3    c  5  6
    4    d  3  2
    5    e  5  4
    6    f  6  1                 
    

    接下来,ggplot 要求它是长格式:

    # Make it into ggplot format
    require(dplyr); require(reshape2)
    df <- df %>%
      melt(id.vars="name")
    
       name variable value
    1     a       x1     5
    2     b       x1     3
    3     c       x1     5
    4     d       x1     3
    5     e       x1     5
    6     f       x1     6
    ...
    

    现在,由于您希望某些条具有不同的颜色,因此我们需要为它们指定一个备用名称,以便我们可以手动分配它们的颜色。

    df <- df %>%
      mutate(variable=ifelse(
        name %in% c("b", "d", "f") & variable == "x1",
        "highlight_x1",
        as.character(variable)))
    
       name     variable value
    1     a           x1     2
    2     b highlight_x1     3
    3     c           x1     4
    4     d highlight_x1     6
    5     e           x1     2
    6     f highlight_x1     6
    7     a           x2     6
    8     b           x2     4
    ...
    

    接下来,我们构建情节。这使用标准颜色:

    require(ggplot2)
    p <- ggplot(data=df, aes(y=value, x=name, fill=factor(variable))) + 
      geom_bar(stat="identity", colour="black") +
      theme_bw() +
      coord_flip(ylim=c(1,10)) # Zooms in on y = c(2,12)
    

    请注意,我使用 coord_flip(又调用 coord_cartesian)和 ylim=c(1,10) 参数来“放大”数据。它不会删除数据,只是忽略它(不像setting the limits in the scale)。现在,如果您手动指定颜色:

    p +  scale_fill_manual(values = c(
        "x1"="coral3",
        "x2"="chartreuse3",
        "highlight_x1"="cornflowerblue"))
    

    【讨论】:

      【解决方案4】:

      我想简化@tedtoal 提出的解决方案,这对我来说是最好的解决方案。

      我想为每个条创建一个具有不同颜色的条形图,而无需使用 ggplot 或生菜。

       color_range<- c(black="#000000", orange="#E69F00", skyblue="#56B4E9", bluegreen="#009E73",yellow="#F0E442", blue="#0072B2", reddish="#D55E00", purplish="#CC79A7")
      
      
      barplot(c(1,6,2,6,1), col= color_range[1:length(c(1,6,2,6,1))])
      

      【讨论】:

        猜你喜欢
        • 2021-03-06
        • 1970-01-01
        • 1970-01-01
        • 2014-05-11
        • 2019-10-02
        • 1970-01-01
        • 1970-01-01
        • 2018-04-07
        • 1970-01-01
        相关资源
        最近更新 更多