Ggplot2: 基于数据集中变量的 facet_敏感条带颜色

有没有一种方法可以根据数据框架提供的变量来填充用 facet _ wraps 创建的面条?

示例数据:

MYdata <- data.frame(fruit = rep(c("apple", "orange", "plum", "banana", "pear", "grape")), farm = rep(c(0,1,3,6,9,12), each=6), weight = rnorm(36, 10000, 2500), size=rep(c("small", "large")))

示例情节:

p1 = ggplot(data = MYdata, aes(x = farm, y = weight)) + geom_jitter(position = position_jitter(width = 0.3), aes(color = factor(farm)), size = 2.5, alpha = 1) + facet_wrap(~fruit)

我知道如何改变条纹的背景颜色(例如橙色) :

p1 + theme(strip.background = element_rect(fill="orange"))

facet_wrap and orange strip color

有没有办法将 MYdata中变量 size的值传递给 element_rect中的参数 fill

基本上,我希望小水果(苹果、李子、梨)的条形背景色是绿色,而大水果(橙色、香蕉、葡萄)的背景色是红色,而不是所有条形的单色。

59747 次浏览

我很想知道如何做到这一点,这是一个伟大的想法。一个想法是独立生成每个图表与不同的颜色,然后使用一些像多图或视图显示,然后并排-这将需要更多的工作。

如果你想提取图例,你需要这种方法-这里有一些代码从哈德利,我找到了一段时间

g_legend<-function(a.gplot){
tmp <- ggplot_gtable(ggplot_build(a.gplot))
leg <- which(sapply(tmp$grobs, function(x) x$name) == "guide-box")
legend <- tmp$grobs[[leg]]
return(legend)}

看看它是如何从图 p 中提取出来的,然后我把它从图中提取出来 图例 <-g _ Legend (p) Lwidth <-sum (图例 $width) # 如果要基于此定义视口,请使用 P <-p + 主题(legend.position = “ none”)

然后你最终会画出来

grid.newpage()
vp <- viewport(width = 1, height = 1)
#print(p, vp = vp)


submain <- viewport(width = 0.9, height = 0.9, x = 0.5, y = 1,just=c("center","top"))
print(p, vp = submain)
sublegend <- viewport(width = 0.5, height = 0.2, x = 0.5, y = 0.0,just=c("center","bottom"))
print(arrangeGrob(legend), vp = sublegend)

祝你好运

通过一些工作,您可以将绘图与具有正确 grobs 的虚拟 gtable 结合起来,

enter image description here

d <- data.frame(fruit = rep(c("apple", "orange", "plum", "banana", "pear", "grape")),
farm = rep(c(0,1,3,6,9,12), each=6),
weight = rnorm(36, 10000, 2500),
size=rep(c("small", "large")))


p1 = ggplot(data = d, aes(x = farm, y = weight)) +
geom_jitter(position = position_jitter(width = 0.3),
aes(color = factor(farm)), size = 2.5, alpha = 1) +
facet_wrap(~fruit)


dummy <- ggplot(data = d, aes(x = farm, y = weight))+ facet_wrap(~fruit) +
geom_rect(aes(fill=size), xmin=-Inf, xmax=Inf, ymin=-Inf, ymax=Inf) +
theme_minimal()


library(gtable)


g1 <- ggplotGrob(p1)
g2 <- ggplotGrob(dummy)


gtable_select <- function (x, ...)
{
matches <- c(...)
x$layout <- x$layout[matches, , drop = FALSE]
x$grobs <- x$grobs[matches]
x
}


panels <- grepl(pattern="panel", g2$layout$name)
strips <- grepl(pattern="strip_t", g2$layout$name)
g2$layout$t[panels] <- g2$layout$t[panels] - 1
g2$layout$b[panels] <- g2$layout$b[panels] - 1


new_strips <- gtable_select(g2, panels | strips)
grid.newpage()
grid.draw(new_strips)


gtable_stack <- function(g1, g2){
g1$grobs <- c(g1$grobs, g2$grobs)
g1$layout <- transform(g1$layout, z= z-max(z), name="g2")
g1$layout <- rbind(g1$layout, g2$layout)
g1
}
## ideally you'd remove the old strips, for now they're just covered
new_plot <- gtable_stack(g1, new_strips)
grid.newpage()
grid.draw(new_plot)

你可以找到这个问题的最新答案 给你

g <- ggplot_gtable(ggplot_build(p))
stripr <- which(grepl('strip-r', g$layout$name))
fills <- c("red","green","blue","yellow")
k <- 1
for (i in stripr) {
j <- which(grepl('rect', g$grobs[[i]]$grobs[[1]]$childrenOrder))
g$grobs[[i]]$grobs[[1]]$children[[j]]$gp$fill <- fills[k]
k <- k+1
}
grid::grid.draw(g)

enter image description here

这并不是直接针对不同颜色的方面,但在这里你有另一个(非常快速和简单)的解决方案,基于方面的两个变量(size ~ fruit) ,而不是一个(~ fruit) :

ggplot(data = MYdata, aes(x = farm, y = weight)) +
geom_jitter(position = position_jitter(width = 0.3),
aes(color = factor(farm)), size = 2.5, alpha = 1) +
facet_wrap(size ~ fruit)

enter image description here