ggplot2:当类别低于零时,堆叠条形标签显示错误的位置和顺序

时间:2018-04-24 23:35:34

标签: r ggplot2

我正在尝试使用ggplot2在R中创建一大组不同的条形图(like those found here)。但是,我无法获取不良类别(堆叠在0以下)的标签,以正确的顺序和正确的位置打印。这是一些可重现的代码:

foo <- data.frame(value=c(2:6)
                  ,percent=c(-.185, -.074, .148, .074, .518)
                  ,col=c("#EF8A62", "#FDDBC7", "#D1E5F0", "#67A9CF", "#2166AC")
                  ,set="Expectations")

semanticLevels <- c("Very Negative"
                    ,"Negative"
                    ,"Slightly Negative"
                    ,"Slightly Positive"
                    ,"Positive"
                    ,"Very Positive")

pal <- brewer.pal(6,"RdBu")

ggplot() + geom_bar(data=foo, aes(x = set, y=percent, fill=col), position="stack", stat="identity") +  
  geom_hline(yintercept = 0, color =c("white")) +
  geom_text(data=foo, aes(x = set, y=percent, label=scales::percent(abs(percent))), position = position_stack(vjust = .5), angle=-90) +
  scale_fill_identity("", labels = semanticLevels, breaks=pal, guide=guide_legend(nrow=1)) +
  coord_flip() +
  scale_y_continuous(breaks=seq(-1,1,.5), limits=c(-1,1),labels=scales::percent) + 
  theme(legend.position = "bottom" )

这会生成以下图表:

Stacked (diverging) bar graph with misplaced data labels

如您所见,所需类别的所有数据标签都以适当的类别为中心,但对于零以下的不良类别,数据标签不按顺序排列,并且不在各自的类别中。

我已经针对这个问题尝试了很多解决方案,并没有提出任何可以解决问题的简单更改。

有没有人有任何想法?

1 个答案:

答案 0 :(得分:1)

由于某种原因ggplot在分别调用每个图层时会弄乱堆叠,但如果允许继承数据和美学,它将正常工作:

foo <- data.frame(value=c(2:6)
                  ,percent=c(-.185, -.074, .148, .074, .518)
                  ,col=c("#EF8A62", "#FDDBC7", "#D1E5F0", "#67A9CF", "#2166AC")
                  ,set="Expectations")

semanticLevels <- c("Very Negative"
                    ,"Negative"
                    ,"Slightly Negative"
                    ,"Slightly Positive"
                    ,"Positive"
                    ,"Very Positive")

pal <- brewer.pal(6,"RdBu")

ggplot(data=foo,aes(x = set, y=percent, fill=col)) + 
  geom_bar(position="stack", stat="identity") +  
  geom_hline(yintercept = 0, color =c("white")) +
  geom_text(aes(label=scales::percent(abs(percent))), position = position_stack(vjust = .5), angle=-90) +
  scale_fill_identity("", labels = semanticLevels, breaks=pal, guide=guide_legend(nrow=1)) +
  coord_flip() +
  scale_y_continuous(breaks=seq(-1,1,.5), limits=c(-1,1),labels=scales::percent) + 
  theme(legend.position = "bottom" )

Done with inheritance

如果您想要一个更令人满意(并且可能更可靠)的解决方案,您可以自己指定定位:

library(dplyr)

foo <- foo %>%
  group_by_all() %>%
  mutate(position = ifelse(value<=3,sum(foo$percent[foo$value>value & foo$value<=3])
                           ,sum(foo$percent[foo$value<value & foo$value>3]))+.5*percent)

ggplot() + 
  geom_bar(data=foo, aes(x = set, y=percent, fill=col), position="stack", stat="identity") +
  geom_text(data=foo, aes(x = set, y=position, label=scales::percent(abs(percent))), position = "identity", angle=-90) +
  geom_hline(yintercept = 0, color =c("white")) +
  scale_fill_identity("", labels = semanticLevels, breaks=pal, guide=guide_legend(nrow=1)) +
  coord_flip() +
  scale_y_continuous(breaks=seq(-1,1,.5), limits=c(-1,1),labels=scales::percent) +
  theme(legend.position = "bottom" )

Done with explicit position