ggplot背景与geom_rect的三种不同颜色不起作用-数据和所有代码

时间:2018-10-12 17:17:09

标签: r ggplot2

可复制的数据:

df <- data.frame(cbind("Thriving" = c(2, 2, NA, runif(9, 2.0, 5.0)), "Performance" = c(2, 3.5, 2.3, 4.2, NA, runif(7, 1.9, 6.9)), "Mastery_Climate" = c(runif(10, 2.2, 6.5), NA, 2.3), "Competitive_Climate" = c(NA, runif(4, 1.0, 3.6), NA, NA, runif(5, 1.5, 2.8)), "Collaboration" = c(runif(8, 2.2, 7.0), NA, NA, 5.5, 2.1)))

使用这些数据,我想使用以下命令对ggplot2和tidyr包创建bloxplots:

df %>%
gather(key = "variable", value = "value") -> n
n$variable <- factor(n$variable, levels = c("Thriving", "Performance", "Mastery_Climate", "Competitive_Climate", "Collaboration"))
ggplot(data = n, aes(y = value, x = variable)) + stat_summary(fun.data = min.mean.sd.max, geom = "boxplot", col = "#323232", fill = "#EFC76C") + 
coord_flip() + scale_y_continuous(breaks = c(1, 2, 3, 4, 5, 6, 7)) +
expand_limits(y = c(1, 7)) +
labs(x = "", y = "") +
theme(text = element_text(size = 12), panel.background = element_rect(fill = "#EAEDED")) +
theme(plot.margin=unit(c(0, 2, 0, 1.8),"cm"))

stat_summary中使用的函数如下:

min.mean.sd.max <- function(x) {
r <- c(min(x), mean(x) - sd(x), mean(x), mean(x) + sd(x), max(x))
names(r) <- c("ymin", "lower", "middle", "upper", "ymax")
r
}

现在,即将到来:一切工作都很漂亮,但是,现在,我想用三种不同的颜色(绿色,黄色和红色)为背景着色。我知道我必须为此使用geom_rect。但是,为了使boxplots处于前台,我需要先传递geom_rect参数-但这会破坏我的代码:

df %>%
gather(key = "variable", value = "value") -> n
n$variable <- factor(n$variable, levels = c("Thriving", "Performance", "Mastery_Climate", "Competitive_Climate", "Collaboration"))
ggplot(data = n, aes(y = value, x = variable)) + 
geom_rect(aes(xmin = -Inf, xmax = Inf, ymin = -Inf, ymax = 3, fill = "green"), alpha = .01) +
geom_rect(aes(xmin = -Inf, xmax = Inf, ymin = 3, ymax = 5, fill = "yellow"), alpha = .01) +
geom_rect(aes(xmin = -Inf, xmax = Inf, ymin = 5, ymax = Inf, fill = "red"), alpha = .01) +
stat_summary(fun.data = min.mean.sd.max, geom = "boxplot", col = "#323232", fill = "#EFC76C") + 
coord_flip() + scale_y_continuous(breaks = c(1, 2, 3, 4, 5, 6, 7)) +
expand_limits(y = c(1, 7)) +
labs(x = "", y = "") +
theme(text = element_text(size = 12), panel.background = element_rect(fill = "#EAEDED")) +
theme(plot.margin=unit(c(0, 2, 0, 1.8),"cm"))

如您所见,我收到错误消息“错误:将离散值提供给连续刻度”。从研究中我了解到,这是因为我需要更改序列,而x变量是一个因素现在是一个问题。但是,我一直无法解决这个问题。 如果所有其他代码都保持不变,那将是很棒的,我花了很长时间才将它们组合在一起。而且,一旦箱线图位于前景中,如果后面的网格仍然可见,那就太好了。此外,我对geom_rect的填充感到困惑,我输入“绿色”,然后变成粉红色,或者输入“黄色”,然后变成蓝色,不知道为什么。 无论如何,非常感谢您的帮助。许多问候!

1 个答案:

答案 0 :(得分:1)

编辑:更新的答案具有更好的阴影控制

我认为这种方法对ggplot更为惯用:将阴影放入带有数字y值的单独表中。在修改的ggplot调用中,所有y值都映射为数字值,但是这些值的标签在scale_y_continuous行中换出了。

rects <- data.frame(xmin = -Inf, 
                    xmax = Inf,
                    ymin = c(0,3,5),  
                    ymax = c(3,5,Inf),
                    fill = c("green", "yellow", "red"))


ggplot(data = n, aes(y = value, x = as.numeric(variable))) + 
  geom_rect(data = rects, aes(xmin = xmin, xmax = xmax, ymin = ymin, ymax = ymax, fill = fill), 
            # Control the shading opacity here.
            inherit.aes = FALSE, alpha = 0.15) +
  stat_summary(fun.data = min.mean.sd.max, geom = "boxplot", col = "#323232", fill = "#EFC76C") + 
  scale_fill_identity() + 
  scale_x_continuous(breaks = as.numeric(unique(n$variable)), minor_breaks = NULL,
                 labels = unique(n$variable)) + 
  scale_y_continuous(breaks = c(1, 2, 3, 4, 5, 6, 7)) +
  expand_limits(y = c(1, 7)) +
  coord_flip() + 
  labs(x = "", y = "") +
  theme(text = element_text(size = 12), panel.background = element_rect(fill = "#EAEDED")) +
  theme(plot.margin=unit(c(0, 2, 0, 1.8),"cm"))

enter image description here


原始答案

geom_rect的坐标应从aes()调用中拉出,然后我得到一个可行的解决方案。但是,这种方法的一个问题是实际上为源数据中的每个元素绘制了一次背景矩形,这就是为什么即使在alpha = 0.01时颜色也是如此明亮的原因。

ggplot(data = n, aes(y = value, x = variable)) + 
  geom_rect(xmin = -Inf, xmax =  Inf, ymin = 0, ymax = 3, fill = "green", alpha = .005) +
  geom_rect(xmin = -Inf, xmax =  Inf, ymin = 3, ymax = 5, fill = "yellow", alpha = .005) +
  geom_rect(xmin =  -Inf, xmax =  Inf, ymin = 5, ymax = 7, fill = "red", alpha = .005) +
  stat_summary(fun.data = min.mean.sd.max, geom = "boxplot", col = "#323232", fill = "#EFC76C") + 
  coord_flip() + scale_y_continuous(breaks = c(1, 2, 3, 4, 5, 6, 7)) +
  expand_limits(y = c(1, 7)) +
  labs(x = "", y = "") +
  theme(text = element_text(size = 12), panel.background = element_rect(fill = "#EAEDED")) +
  theme(plot.margin=unit(c(0, 2, 0, 1.8),"cm"))