r - 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
任何想法?
任何帮助将不胜感激:) 非常感谢!瓦莱里安
解决方案
预先:这是一个部分答案,还有两个值得注意的问题需要解决(见最后)。 编辑:这两个问题已经解决,见最底部。
我将稍微更改“闪避”以澄清这一点,确定关注的领域,并展示建议的解决方法。
# 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)
也就是说,我假设我们想要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)
)
})
(旁注:我在这里使用levels(d2$treatment)
and data=~subset(., treatment==trtmnt)
,但这只是一种方法。另一种方法是在所有内部几何中lapply(split(d2, d2$treatment), function(x) ...)
使用data=x
。如果需要,后一种方法允许多变量分组。我看不到一个直接的优势在另一个之上。)
这样做的问题:
- 图例的顺序与因子水平的顺序不一致,不知何故丢失了。(要清楚,我在这里没有很好地证明这一点:我可以使用 将“中”移动到图例的中间
levels<-
,并且它适用于具有不正确分层的非lapply
渲染代码,但它再次丢失lapply
-几何学。) 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)
推荐阅读
- python - 添加2个不同长度的列表列表
- javascript - 如何防止隐藏按钮阻止链接被点击
- mysql - 如何在 heroku 的 laravel 项目中添加另一个数据库
- javascript - 如何将.js文件中的Vue对象导入html
- firebase - 如何在颤振中使用提供者状态初始化控制器
- xamarin.android - Xamarin.Android 中的 FindViewByID 无法识别 ..axml 中定义的 ID
- c++ - 巨大的静态数组与函数内的本地数组
- apache-zookeeper - Zookeper 授权如何运作?
- flutter - 如何在 Flutter 上的 Sqflite 上创建复杂模型
- react-native - 在反应原生 android 应用程序中打开应用程序通知设置?