使用正负值标记堆叠的条形图

时间:2019-02-28 20:37:07

标签: r ggplot2 label bar-chart

我正在使用ggplot2创建具有负值的堆叠条形图,并尝试将各部分的总和作为标签添加到每个条形图的顶部。该代码对于没有负值的条能正常工作,但是当存在负值时,标签会留在条内。

示例:

test = c("Test1", "Test1", "Test1", "Test2", "Test2", "Test2", "Test3", "Test3", "Test3")  
student = c("A", "B", "C", "A", "B", "C", "A", "B", "C")  
value = c(5,5,5,3,3,3,-2,6,7)

dummy = data.frame(test, student, value)

g = ggplot(data=dummy, aes(x=student, y=value, fill=test)) +   
      geom_bar(stat="identity") +   
      scale_fill_manual(values=c("brown4", "steelblue", "goldenrod3")) +
      geom_text(aes(label=value), size =3, position=position_stack(vjust=0.5), colour="white") +
      theme_classic() + 
      theme(text=element_text(family="serif", size=15, colour="black")) +   
      theme(axis.title=element_text(family="serif", size=15, colour="black")) +   
      theme(legend.title = element_blank()) +   
      theme(legend.position = c(0.2, 0.7)) +
      stat_summary(fun.y = sum, aes(label = ..y.., group = student), geom = "text", vjust = -1) +
      scale_y_continuous(limits = c(-4,20))

g

结果如下图所示:

Chart with stacked bars and negative values 没有负值的条的总和在条的顶部效果很好,但是具有负值的条的总和(学生A)在红色条的中间。

我该如何解决?

1 个答案:

答案 0 :(得分:1)

您将fun.y = sum用作汇总函数,该函数将组中的所有y值相加,包括负值。这样可以得出正确的标签总和,但位置不好。对于位置计算,我们只想计算大于0的值之和。

stat_summary让我们指定多达3个功能,fun.yfun.yminfun.ymax。我们将位置fun.y修改为正值的总和,并添加fun.ymax作为常规sum并将其用于标签:

g = ggplot(data=dummy, aes(x=student, y=value, fill=test)) +   
      geom_bar(stat="identity") +   
      scale_fill_manual(values=c("brown4", "steelblue", "goldenrod3")) +
      geom_text(aes(label=value), size =3, position=position_stack(vjust=0.5), colour="white") +
      theme_classic() + 
      theme(text=element_text(family="serif", size=15, colour="black")) +   
      theme(axis.title=element_text(family="serif", size=15, colour="black")) +   
      theme(legend.title = element_blank()) +   
      theme(legend.position = c(0.2, 0.7)) +
      stat_summary(fun.y = function(y) sum(y[y > 0]), fun.ymax = sum,
                   aes(label = ..ymax.., group = student), geom = "text", vjust = -1) +
      scale_y_continuous(limits = c(-4,20))
g

enter image description here