r堆积条形图与颜色代表值

时间:2015-05-27 15:18:17

标签: r colors bar-chart stacked-chart

我希望制作一个堆叠的条形图,其颜色代表来自单独数据列的值,并且仅使用R 中的基本图形添加准确的颜色条。还有一篇关于此的帖子,但它非常混乱,最终没有帮助我回答我的问题。

# create reproducible data
d <- read.csv(text='Day,Location,Length,Amount
            1,4,3,1.1
            1,3,1,.32
            1,2,3,2.3
            1,1,3,1.1
            2,0,0,0
            3,3,3,1.8
            3,2,1,3.54
            3,1,3,1.1',header=T)

# colors will be based on values in the Amount column
v1 <- d$Amount
# make some colors based on Amount - normalized
z <- v1/max(v1)*1000
colrs <- colorRampPalette(c('lightblue','blue','black'))(1000)[z]

# create a 2d table of the data needed for plotting
tab <- xtabs(Length ~ Location + Day, d)
# create a stacked bar plot
barplot(tab,col=colrs,space=0)

# create a color bar
plotr::color.bar

这肯定会生成彩色编码堆积条形图,但颜色并不能准确表示数据。

对于第1天,位置4和1的颜色应相同。另一个例子,Amount列中的第一个和最后一个条目是相同的,但左列顶部的颜色与右列的底部不匹配。

另外,我找到了如何在不同的帖子上制作颜色条并使用plotr::color.bar代码,但plotr显然不是包裹,我不知道如何继续

如何让颜色与相应的部分匹配并添加准确的颜色条?

3 个答案:

答案 0 :(得分:0)

基于以下评论:

library(ggplot2)
ggplot(d, aes(x = Day, y = Length)) + geom_bar(aes(fill = Amount, order = Location), stat = "identity") 

答案 1 :(得分:0)

我认为这是定义颜色的错误,条形图只需要5种颜色,因为有5个位置,其中一种颜色不会被使用,因为位置1每天都有零元素。

<强>修正:

colrs <- colorRampPalette(c('yellow', 'lightblue','blue','black', 'lightblue'))(5)

output after fixing colrs vector

请注意&#39;黄色&#39;没有被绘制,因为它的组中有0个观察结果(来自OP的样本数据)

答案 2 :(得分:0)

我希望“非常混乱”的帖子不是我How to create a time series plot in the style of a horizontal stacked bar plot in r的答案!那没关系,没有冒犯。

解决方案可以按照以下方式适应您的数据:

## store data
df <- read.csv(text='Day,Location,Length,Amount\n1,4,3,1.1\n1,3,1,.32\n1,2,3,2.3\n1,1,3,1.1\n2,0,0,0\n3,3,3,1.8\n3,2,1,3.54\n3,1,3,1.1',header=T);

## extract bar segment lengths from Length and bar segment colors from a function of Amount, both stored in a logical matrix form
lengths <- xtabs(Length~Location+Day,df);
amounts <- xtabs(Amount~Location+Day,df);
colors <- matrix(colorRampPalette(c('lightblue','blue','black'))(1001)[amounts/max(amounts)*1000+1],nrow(amounts));

## transform lengths into an offset matrix to appease design limitation of barplot(). Note that colors will be flattened perfectly to accord with this offset matrix
lengthsOffset <- as.matrix(setNames(reshape(cbind(id=1:length(lengths),stack(as.data.frame(unclass(lengths)))),dir='w',timevar='ind')[-1],colnames(lengths)));
lengthsOffset[is.na(lengthsOffset)] <- 0;

## draw plot
barplot(lengthsOffset,col=colors,space=0,xlab='Day',ylab='Length');

offset-stacked-barplot

备注

  • 在您的问题中,您尝试使用colrs <- colorRampPalette(c('lightblue','blue','black'))(1000)[z]构建颜色向量,其中z是转换为“每千米”形式的8个原始Amount值。这有一个轻微的缺陷,因为其中一个z元素为零,这不是一个有效的索引值。这就是为什么你有7种颜色,当它应该是8.我通过在每个mille值中加1并生成1001种颜色来修复我的代码。
  • 还与生成颜色有关,而不是仅生成8种颜色(即每个原始Amount值一个颜色),我生成了一个完整的颜色矩阵,以平行lengths矩阵(您称之为{{代码中的1}}。这个颜色矩阵实际上可以直接用作传递给tab的{​​{1}}参数的颜色向量,因为它在内部被展平为向量(至少在概念上)并且将与偏移条段长度对应我们将barplot()参数传递给col(参见下一个注释)。
  • 正如我在前面提到的帖子中更详细地描述的那样,该解决方案的关键是创建条形段长度的“偏移矩阵”,其中相邻列中的零点,使得可以为每个段分配不同的颜色。我从barplot()矩阵创建height
  • 请注意,或许有点违反直觉,lengthsOffset参数中较低的索引值由lengths作为较低的段绘制,反之亦然,这意味着在打印该数据时的文本显示您的终端与条形图中的显示方式垂直相反。如果您想要相反的顺序,可以垂直反转height矩阵和barplot()向量,但我的代码中没有这样做。

供参考,以下是所有数据结构:

lengthsOffset