繁体   English   中英

为什么 geom_rect 只为 facet_wrap 的第一行着色?

[英]Why geom_rect colours only first row of facet_wrap?

我试图在我的facet_wrap图的每个偶数面板上获得阴影矩形。 但是,当我使用geom_rect时,它仅在第二个面板上生成矩形。 我尝试使用annotategeom_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)

虽然您的想法是正确的,恕我直言,您可以通过将xminxmax值放入数据框中并通过美学映射来更轻松地实现您想要的结果。 首先注意,我们只需要一个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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM