ggplot堆叠条的奇怪排序

时间:2017-06-06 12:36:41

标签: r ggplot2 dplyr

我正在尝试创建一个像here这样的分散堆叠条,并且遇到与此SO question类似的问题。我的方法略有不同,因为我通过单个数据集管理它,而不是两个,我的颜色与我的数据无关。

表示如下:

library(tidyverse)
library(RColorBrewer)
x <- tribble(
  ~response, ~count,
  0,         -27,
  1,          -9,
  2,         -41,
  3,         -43,
  4,         -58,
  5,        -120,
  5,         120,
  6,         233,
  7,         379,
  8,         388,
  9,         145,
  10,         61
) %>% 
  mutate(response = factor(response))

ggplot(x, aes(x = 1, y = count, fill = response)) +
  geom_col() +
  scale_fill_brewer(palette = "RdBu") +
  coord_flip()

这给我一个像这样的图像:enter image description here

问题在于零的右侧堆叠数据的排序,它们的堆叠似乎是降序排列。任何关于如何解决这个问题的想法都将非常感激(预期订购将是0-10,而不是0-5,10-5)

3 个答案:

答案 0 :(得分:2)

一个艰难的人!我玩了排序,当你以相同的顺序组合正值和负值时,似乎geom_bargeom_col不喜欢它。因此,我将数据在数据框内划分为正值和负值,为每个响应值生成颜色,并分别使用两个geom作为正值和负值:

library(tidyverse)
library(RColorBrewer)
x <- tribble(
  ~response, ~count,
  0,         -27,
  1,          -9,
  2,         -41,
  3,         -43,
  4,         -58,
  5,        -120,
  5,         120,
  6,         233,
  7,         379,
  8,         388,
  9,         145,
  10,         61
) %>% 
  # Get absolute values and add dummy to distuingish positive and negative values
  mutate(subzero = count < 0,
         count = abs(count))

# Generate variable with colors from ColorBrewer for every response level (ugly but works)
colors <- brewer.pal(length(unique(x$response)),"RdBu")
x$colors <- NA
for (i in 1:nrow(x)){
  x$colors[i] <- colors[x$response[i]+1]
}


ggplot() +
  geom_bar(data = x[x$subzero==T,], aes(x = "", y = -count, fill = reorder(colors, response)), position="stack", stat="identity") +
  geom_bar(data = x[x$subzero==F,], aes(x = "", y = count, fill = reorder(colors, -response)), position="stack", stat="identity") +
  geom_hline(yintercept = 0, color =c("black")) +
  scale_fill_identity("Response", labels = unique(x$response), breaks=unique(x$colors), guide="legend") +
  coord_flip() +
  labs(y="",x="") +
  theme(legend.position = "bottom", legend.direction = "horizontal") +
  scale_y_continuous(breaks=seq(-1400,1400,200), limits=c(-1400,1400))
UPD:Y尺度平衡,看起来更清晰 enter image description here

答案 1 :(得分:1)

虽然不直观(对我来说),但请使用:

ggplot(x, aes(x = 1, y = order(count), fill = response)) +
  geom_col() +
  scale_fill_brewer(palette = "RdBu",direction=1) +
  coord_flip()

它考虑了基于响应的排序(而不是顺序(响应))

答案 2 :(得分:0)

您可以使用position_stack(reverse=TRUE)

ggplot(x, aes(x = 1, y = count, fill = response)) +
  geom_col(position = position_stack(reverse=TRUE)) +
  scale_fill_brewer(palette = "RdBu") +
  coord_flip()