首页 > 解决方案 > ggplot2 - 线条和误差线重叠的问题

问题描述

在同一个 ggplot 图上,我试图将点(从geom_point)、线(从geom_line)和误差条(从geom_errorbar)放在同一个“平面”(即不重叠)上,这适用于每个因素。

如您所见,误差条的“分层”并未遵循线条的“分层”(未提及点)。

点、线和误差线不在同一位置

这是一个可重现的示例:

# reproducible example

# package
library(dplyr)
library(ggplot2)

# generate the data

set.seed(244)

d1 <-  data.frame(time_serie = as.factor(rep(rep(1:3, each = 6), 3)),
                  treatment = as.factor(rep(c("HIGH", "MEDIUM", "LOW"), each = 18)),
                  value = runif(54, 1, 10))

# create the error intervals

d2 <- d1 %>%
  dplyr::group_by(time_serie,treatment) %>%
  dplyr::summarise(mean_value = mean(value), 
                   SE_value = sd(value/sqrt(length(value)))) %>%
  as.data.frame()

# plot 
p1 <- ggplot(aes(x = time_serie, y = mean_value, color = treatment, group = treatment), data=d2) 
p1
p1a <- p1 + geom_errorbar(aes(ymin = mean_value - SE_value, ymax = mean_value + SE_value), width = .2, position = position_dodge(0.3), size =1) +
  geom_point(aes(), position = position_dodge(0.3), size = 3) + 
  geom_line(aes(color = treatment), position=position_dodge(0.3), size =1)
p1a

任何想法?

任何帮助将不胜感激:) 非常感谢!瓦莱里安

标签: rggplot2

解决方案


预先:这是一个部分答案,还有两个值得注意的问题需要解决(见最后)。 编辑:这两个问题已经解决,见最底部。

我将稍微更改“闪避”以澄清这一点,确定关注的领域,并展示建议的解决方法。

# generate the data
set.seed(244)
d1 <-  data.frame(time_serie = as.factor(rep(rep(1:3, each = 6), 3)),
                  treatment = as.factor(rep(c("HIGH", "MEDIUM", "LOW"), each = 18)),
                  value = runif(54, 1, 10))

# create the error intervals
d2 <- d1 %>%
  dplyr::group_by(time_serie,treatment) %>%
  dplyr::summarise(mean_value = mean(value), 
                   SE_value = sd(value/sqrt(length(value)))) %>%
  dplyr::arrange(desc(treatment)) %>%
  as.data.frame()

# plot 
ggplot(aes(x = time_serie, y = mean_value, color = treatment, group = treatment), data=d2) +
  geom_errorbar(aes(ymin = mean_value - SE_value, ymax = mean_value + SE_value),
                width = 0.2, position = position_dodge(0.03), size = 2) +
  geom_point(aes(), position = position_dodge(0.03), size = 3) + 
  geom_line(aes(color = treatment), position = position_dodge(0.03), size = 2)

ggplot2 混合分层

也就是说,我假设我们想要HIGH(红色)点/线/误差条作为最顶层,什么都没有。我们可以在最右边的栏中看到明显的违规行为:红点在绿色错误栏上方但在绿线下方。

放大到混合分层

除非/直到有aes(layer=..)审美(没有 afaik),您需要一次添加一层treatment。虽然可以使用九个几何图形对其进行硬编码,但您可以使用lapply. 请注意ggplot(.) + list(geom1,geom2,geom3),即使使用嵌套列表,它也可以正常工作。

我将控制层的顺序rev(levels(d2$treatment)),假设您希望LOW作为最底层(ergo首先添加)。中的几何顺序list是定义它们的层的原因。从技术上讲,我们在不同的层上仍然有单个处理的误差条、点和线,但它们是连续的,因此看起来是相同的。

ggplot(aes(x = time_serie, y = mean_value, color = treatment, group = treatment), data=d2) +
  lapply(rev(levels(d2$treatment)), function(trtmnt) {
    list(
      geom_errorbar(data = ~ subset(., treatment == trtmnt),
                    aes(ymin = mean_value - SE_value, ymax = mean_value + SE_value),
                    width = 0.2, position = position_dodge(0.03), size = 2),
        geom_point(data = ~ subset(., treatment == trtmnt), aes(), position = position_dodge(0.03), size = 3),
        geom_line(data = ~ subset(., treatment == trtmnt), position = position_dodge(0.03), size = 2)
    )
  })

固定分层的ggplot2

(旁注:我在这里使用levels(d2$treatment)and data=~subset(., treatment==trtmnt),但这只是一种方法。另一种方法是在所有内部几何中lapply(split(d2, d2$treatment), function(x) ...)使用data=x。如果需要,后一种方法允许多变量分组。我看不到一个直接的优势在另一个之上。)

这样做的问题:

  1. 图例的顺序与因子水平的顺序不一致,不知何故丢失了。(要清楚,我在这里没有很好地证明这一点:我可以使用 将“中”移动到图例的中间levels<-,并且它适用于具有不正确分层的非lapply渲染代码,但它再次丢失lapply-几何学。)
  2. position_dodge不再了解其他处理,因此它不会躲避其他错误栏。解决此问题的唯一方法(此处未演示)是在绘图前手动躲避,如下所示。

1:图例元素的顺序

这个问题在lapply'd geoms lost factor-ordering中得到了解决,我们只需要添加scale_color_discrete(drop=FALSE).

2:闪避

这个dodge问题可以通过在x美学中使用实数来解决。这是一种黑客行为,因为它不再由外部完成ggplot2而是由外部控制。它本身也应用了偏移而不是躲避。但它确实得到了预期的结果。

d2$time_serie2 <- as.integer(as.character(d2$time_serie)) + as.numeric(d2$treatment)/10

ggplot(aes(x = time_serie2, y = mean_value, color = treatment, group = treatment), data = d2) +
  lapply(rev(levels(d2$treatment)), function(trtmnt) {
    list(
      geom_errorbar(data = ~ subset(., treatment == trtmnt),
                    aes(ymin = mean_value - SE_value, ymax = mean_value + SE_value),
                    width = 0.2, size = 2),
        geom_point(data = ~ subset(., treatment == trtmnt), aes(), size = 3),
        geom_line(data = ~ subset(., treatment == trtmnt), size = 2)
    )
  }) +
  scale_color_discrete(drop = FALSE)

一切都修复了:-)


推荐阅读