如何为分组箱线图中的每个面板设置背景颜色?

How to set background color for each panel in grouped boxplot?

我绘制了一个分组箱线图并尝试更改每个面板的背景颜色。我可以使用 panel.background 函数来更改整个绘图背景。但是如何为单个面板完成此操作?我发现了一个类似的问题here。但是我没有将代码应用到我的情节中。

我的输入数据的前几行看起来像

代码

p<-ggplot(df, aes(x=Genotype, y=Length, fill=Treatment)) +  scale_fill_manual(values=c("#69b3a2", "#CF7737"))+
geom_boxplot(width=2.5)+ theme(text = element_text(size=20),panel.spacing.x=unit(0.4, "lines"),
                             axis.title.x=element_blank(),axis.text.x=element_blank(),axis.ticks.x=element_blank(),axis.text.y = element_text(angle=90, hjust=1,colour="black")) +
labs(x = "Genotype", y = "Petal length (cm)")+
facet_grid(~divide,scales = "free", space = "free")
p+theme(panel.background = element_rect(fill = "#F6F8F9", colour = "#E7ECF1"))

不幸的是,与其他 theme 元素一样,element_rect()fill 美学无法映射到数据。您也不能只将颜色矢量发送到 fill(创建您自己的各种映射)。最后,最简单的解决方案可能会与 the answer you linked to in your question 非常相似......这里有点扭曲。

我将以 mtcars 为例。请注意,我正在将数据集中的一些连续变量转换为因子,以便我们可以创建更多离散值。

需要注意的是,矩形 geom 在箱线图 geom 之前绘制,以确保箱线图出现在矩形的顶部。

ggplot(mtcars, aes(factor(carb), disp)) +
  geom_rect(
    aes(fill=factor(carb)), alpha=0.5,
    xmin=-Inf, xmax=Inf, ymin=-Inf, ymax=Inf) +
  geom_boxplot() +
  facet_grid(~factor(carb), scales='free_x') +
  theme_bw()

全部完成...但还不完全。出了点问题,如果您注意图例上的方框和绘图面板中的网格线,您可能会注意到这一点。看起来某些方面的 alpha 值不正确,而其他方面则没问题。这是怎么回事?

嗯,这与 geom_rect 的工作原理有关。它在每个绘图面板上绘制一个框,但就像其他 geom 一样,它被映射到数据。尽管 geom_rectxy 美学实际上并未用于绘制矩形,但它们用于指示 每个矩形有多少 绘制。这意味着在每个方面绘制的矩形数对应于数据集中存在于该方面的行数。如果存在 3 个观察值,则绘制 3 个矩形。如果一个方面存在 20 个观察值,则绘制 20 个矩形,依此类推

因此,解决方法是提供一个数据框,其中包含每个方面的每个观察值。然后我们必须确保我们提供包含在 ggplot 调用中的任何和所有其他美学(此处为 xy),否则我们将收到错误指示 ggplot 无法“找到”该特定列。请记住,即使 geom_rect 不使用这些进行绘图,它们也用于确定存在多少观察值(以及因此绘制多少)。

rect_df <- data.frame(carb=unique(mtcars$carb))  # supply one of each type of carb

# have to give something to disp
rect_df$disp <- 0

ggplot(mtcars, aes(factor(carb), disp)) +
  geom_rect(
    data=rect_df,
    aes(fill=factor(carb)), alpha=0.5,
    xmin=-Inf, xmax=Inf, ymin=-Inf, ymax=Inf) +
  geom_boxplot() +
  facet_grid(~factor(carb), scales='free_x') +
  theme_bw()

那就更好了。