简体   繁体   English

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

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

I am trying to get shaded rectangles on every even-numbered panel of my facet_wrap plot.我试图在我的facet_wrap图的每个偶数面板上获得阴影矩形。 However, when I use geom_rect , it produces the rectangles only on the second panel.但是,当我使用geom_rect时,它仅在第二个面板上生成矩形。 I tried using annotate and geom_tile but with no success.我尝试使用annotategeom_tile但没有成功。 I presume I am missing some simple detail here, probably related to the fact that my X variable is categorical and not numeric, but I am fighting this for a few hours already...我想我在这里遗漏了一些简单的细节,可能与我的 X 变量是分类而不是数字的事实有关,但我已经为此奋斗了几个小时......

Here is my code:这是我的代码:

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)

And the resulting plot: resulting plot with geom_rect and facet_wrap not working as expected结果图: geom_rect 和 facet_wrap 的结果图未按预期工作

Edit:编辑:

I have created a dummy dataset example which replicates my issue:我创建了一个虚拟数据集示例来复制我的问题:

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)

While your idea was right IMHO you could achieve your desired result more easily by putting the xmin and xmax values in a dataframe and by mapping on aesthetics.虽然您的想法是正确的,恕我直言,您可以通过将xminxmax值放入数据框中并通过美学映射来更轻松地实现您想要的结果。 First note that we only need a vector of even numbers of length(unique(df.tmp$Cnd)) , ie the number of categories of Cnd .首先注意,我们只需要一个length(unique(df.tmp$Cnd)) ,即Cnd的类别数。 Second, as we are mixing discrete and continuous x variables I added an scale_x_discrete before geom_rect as otherwise we will get an error.其次,当我们混合离散和连续 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)

EDIT Just in case.编辑以防万一。 The reason why your approach did not work is that the relevant part of the data used for the rects contains only the far group.您的方法不起作用的原因是用于 rects 的数据的相关部分仅包含far组。 The issue is that basically only rects corresponding to even numbers in the range 1 to 4 (the number of Cnd categories) are displayed.问题是基本上只显示对应于 1 到 4 范围内的偶数( Cnd类别的数量)的矩形。 As can be seen from the following code snippet which replicates the data which under the hood is used for the rects in your approach only the far grp is present (after filtering for even numbers in the range 1 to 4):从下面的代码片段可以看出,它复制了在你的方法中用于矩形的数据,只有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

I have been trying to understand why only the second segment gets shaded.我一直试图理解为什么只有第二段被遮蔽。 Eventually I prepared a second example, in which I have found another possible solution.最后我准备了第二个例子,在其中我找到了另一种可能的解决方案。 However, I am not fully satisfied as I did not understand the issue with geom_rect / facet_wrap ;但是,我并不完全满意,因为我不了解geom_rect / facet_wrap的问题; I only found some workaround.我只找到了一些解决方法。

Here's the example:这是示例:

# 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)

As you can see here, the plot has shaded rectangles only in the second row, despite ensuring the df.tmp[even_numbers, ] includes close datapoints as well:正如您在此处看到的,尽管确保df.tmp[even_numbers, ]也包含close的数据点,但该图仅在第二行中具有阴影矩形: 第一行中的非阴影段

Here I change the ggplot so it contains geom_rect separately for close and far segments:在这里,我更改了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)

As you can see below, it works now:正如您在下面看到的,它现在可以工作了: 在此处输入图像描述

As I mentioned earlier, I am still not sure why geom_rect did not work in the first place.正如我之前提到的,我仍然不确定为什么geom_rect开始就不起作用。 In my solution, a separate geom_rect needs to be prepared for each segment, so it's definitely not a solution for a plot with many of them.在我的解决方案中,需要为每个分段准备一个单独的geom_rect ,因此对于包含许多分段的绘图来说,这绝对不是一个解决方案。 I was trying to find a more elegant way, so one wouldn't have to bother how many segments or other groupings are declared.我试图找到一种更优雅的方式,这样就不必担心声明了多少段或其他分组。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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