[英]Why geom_rect colours only first row of facet_wrap?
我试图在我的facet_wrap
图的每个偶数面板上获得阴影矩形。 但是,当我使用geom_rect
时,它仅在第二个面板上生成矩形。 我尝试使用annotate
和geom_tile
但没有成功。 我想我在这里遗漏了一些简单的细节,可能与我的 X 变量是分类而不是数字的事实有关,但我已经为此奋斗了几个小时......
这是我的代码:
even_numbers <- seq(2,nrow(df.plt),2)
ggplot(df.plt) +
geom_rect(data = df.plt[even_numbers, ],
xmin = even_numbers - 0.5, xmax = even_numbers + 0.5,
ymin = -Inf, ymax = Inf, alpha = 0.3, fill = 'grey') +
geom_boxplot(aes(x = Cnd, y = nst, fill = Srs), position = position_dodge(0.9), outlier.shape = 1) +
facet_wrap(vars(Grp), ncol=1)
结果图: geom_rect 和 facet_wrap 的结果图未按预期工作
编辑:
我创建了一个虚拟数据集示例来复制我的问题:
set.seed(002) # just to make it reproducible
df.tmp = data.frame(nst = rnorm(100*2), Srs = sample(rep(c("S3","S4"),100)), Cnd = sample(rep(c("DN","DA","DV","DAV"),50)), Grp = sample(rep(c("close","far"),100)))
even_numbers <- seq(2,nrow(df.tmp),2)
ggplot(df.tmp) +
geom_rect(data = df.tmp[even_numbers, ],
xmin = even_numbers - 0.5, xmax = even_numbers + 0.5,
ymin = -Inf, ymax = Inf, alpha = 0.3, fill = 'grey') +
geom_boxplot(aes(x = Cnd, y = nst, fill = Srs), position = position_dodge(0.9), outlier.shape = 1) +
facet_wrap(vars(Grp), ncol=1)
虽然您的想法是正确的,恕我直言,您可以通过将xmin
和xmax
值放入数据框中并通过美学映射来更轻松地实现您想要的结果。 首先注意,我们只需要一个length(unique(df.tmp$Cnd))
,即Cnd
的类别数。 其次,当我们混合离散和连续 x 变量时,我在scale_x_discrete
之前添加了一个geom_rect
,否则我们会得到一个错误。
library(ggplot2)
even_numbers <- seq(2, length(unique(df.tmp$Cnd)), 2)
rects <- data.frame(
xmin = even_numbers - 0.5,
xmax = even_numbers + 0.5
)
ggplot(df.tmp) +
scale_x_discrete() +
geom_rect(
data = rects, aes(xmin = xmin, xmax = xmax),
ymin = -Inf, ymax = Inf, alpha = 0.3, fill = "grey"
) +
geom_boxplot(aes(x = Cnd, y = nst, fill = Srs), position = position_dodge(0.9), outlier.shape = 1) +
facet_wrap(vars(Grp), ncol = 1)
编辑以防万一。 您的方法不起作用的原因是用于 rects 的数据的相关部分仅包含far
组。 问题是基本上只显示对应于 1 到 4 范围内的偶数( Cnd
类别的数量)的矩形。 从下面的代码片段可以看出,它复制了在你的方法中用于矩形的数据,只有far
grp 存在(在过滤了 1 到 4 范围内的偶数之后):
even_numbers <- seq(2,nrow(df.tmp),2)
dplyr::bind_cols(df.tmp[even_numbers, ], data.frame(even_number = even_numbers)) |>
dplyr::filter(even_number <= 4)
#> nst Srs Cnd Grp even_number
#> 1 0.1848492 S3 DV far 2
#> 2 -1.1303757 S3 DA far 4
我一直试图理解为什么只有第二段被遮蔽。 最后我准备了第二个例子,在其中我找到了另一种可能的解决方案。 但是,我并不完全满意,因为我不了解geom_rect
/ facet_wrap
的问题; 我只找到了一些解决方法。
这是示例:
# constructing the dataframe so all the combinations are present for both even and odd rows
df.tmp = data.frame(nst = rnorm(16*6),
Srs = rep(c("S3", "S4"), each=8, 6),
Cnd = rep(c("DN", "DA", "DV", "DAV"), each=2, 12),
Grp = rep(c(rep(c("close","far"), 8), rev(rep(c("close","far"), 8))),3) )
even_numbers <- seq(2,nrow(df.tmp),2) # so the df.tmp[even_numbers, ] contains all the combinations
ggplot(df.tmp) +
geom_rect(data = df.tmp[even_numbers, ],
xmin = even_numbers - 0.5, xmax = even_numbers + 0.5,
ymin = -Inf, ymax = Inf, alpha = 0.3, fill = 'grey') +
geom_boxplot(aes(x = Cnd, y = nst, fill = Srs), position = position_dodge(0.9), outlier.shape = 1) +
facet_wrap(vars(Grp), ncol=1)
正如您在此处看到的,尽管确保df.tmp[even_numbers, ]
也包含close
的数据点,但该图仅在第二行中具有阴影矩形:
在这里,我更改了ggplot
,使其分别包含close
段和far
段的geom_rect
:
even_numbers <- seq(2,length(unique(df.tmp$Cnd)),2) # here the df.tmp[even_numbers, ] doesn't need to have all the combinations
ggplot(df.tmp) +
geom_rect(data = df.tmp[df.tmp$Grp=="close", ][even_numbers, ],
xmin = even_numbers - 0.5, xmax = even_numbers + 0.5,
ymin = -Inf, ymax = Inf, alpha = 0.3, fill = 'grey') +
geom_rect(data = df.tmp[df.tmp$Grp=="far", ][even_numbers, ],
xmin = even_numbers - 0.5, xmax = even_numbers + 0.5,
ymin = -Inf, ymax = Inf, alpha = 0.3, fill = 'grey') +
geom_boxplot(aes(x = Cnd, y = nst, fill = Srs), position = position_dodge(0.9), outlier.shape = 1) +
facet_wrap(vars(Grp), ncol=1)
正如我之前提到的,我仍然不确定为什么geom_rect
开始就不起作用。 在我的解决方案中,需要为每个分段准备一个单独的geom_rect
,因此对于包含许多分段的绘图来说,这绝对不是一个解决方案。 我试图找到一种更优雅的方式,这样就不必担心声明了多少段或其他分组。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.