ggplot2:基于数据集中变量的facet_wrap条带颜色

4bbkushb  于 2023-01-06  发布在  其他
关注(0)|答案(5)|浏览(213)

有没有一种方法可以根据数据框提供的变量填充facet_wrap创建的小平面条带?
示例数据:
第一个月
示例图:
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"))

是否有办法将MYdata中变量size中的值传递给element_rect中的参数fill
基本上,我希望小水果(苹果、李子、梨)的背景色为绿色,大水果(橙子、香蕉、葡萄)的背景色为红色,而不是所有条带的1种颜色。

yxyvkwin

yxyvkwin1#

只需做一点工作,您就可以将绘图与具有正确grob的虚拟gtable结合起来,

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

v2g6jxz62#

您可以找到此问题的更新答案here

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)

c3frrgcw

c3frrgcw3#

我很想知道如何做到这一点,这是一个伟大的想法。一个想法是生成每个图表独立与不同的颜色,因为你这样做,然后使用一些像multiplot或视口显示,然后并排-这将需要更多的工作。
如果你想提取图例,你将需要这种方法-这里是一些代码从哈德利,我发现了一段时间回来

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(legend$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)

祝你好运

agxfikkp

agxfikkp4#

这不是直接为你的facet着色,但这里你有另一个(非常快速和简单)的解决方案,基于facet由两个变量(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)

xmq68pz9

xmq68pz95#

如果你想对条带背景进行不同的填充,你可以使用ggh 4x中的facets来设置strip_themed()中更复杂的条带。没有gtables的麻烦,你的绘图仍然是ggplot,所以你可以在之后添加常用的图层/比例/主题选项等。

library(ggh4x)
#> Loading required package: ggplot2

# Only colour strips in x-direction
strip <- strip_themed(background_x = elem_list_rect(fill = rainbow(7)))

# Wrap variant
ggplot(mpg, aes(displ, hwy)) +
  geom_point() +
  facet_wrap2(~ class, strip = strip)

它也适用于网格布局,但是如果你想给垂直条着色,你还需要在strip_themed()中设置background_y参数。

ggplot(mpg, aes(displ, hwy)) +
  geom_point() +
  facet_grid2(year ~ cyl, strip = strip)

reprex package(v2.0.1)于2023年1月4日创建
免责声明:我是ggh 4x的作者

相关问题