【问题标题】:ggplot2: facet_wrap strip color based on variable in data setggplot2:基于数据集中变量的 facet_wrap 条带颜色
【发布时间】:2013-10-26 17:32:40
【问题描述】:

有没有办法根据数据框提供的变量填充使用 facet_wrap 创建的分面条?

示例数据:

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

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

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

【问题讨论】:

  • 没有一个简单的方法可以做到这一点,it has been asked before 在另一个网站上。
  • 谢谢,nograpes。我看了看,但找不到以前问过的地方。
  • 如果您让该代码工作,您应该将其发布为答案。
  • 我很想知道该怎么做,这是个好主意
  • 此功能+1。能够在主题中指定会很好。

标签: r ggplot2 facet-wrap


【解决方案1】:

通过一些工作,您可以将您的情节与具有正确 grobs 的虚拟 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)

【讨论】:

  • 这只是[R]震撼了我的世界!多年来一直在尝试这样做!
  • @duckertito 你本来可以编辑帖子的。我现在做到了。在当前版本 ggplot2_2.2.1 中,您必须使用 grepl 查找“strip-t”而不是 strip_t。在我的编辑中也改变了这一点。顺便说一句,感谢您提供的好解决方案!
  • 是的,对我也有用(@andrasz 更改)。我希望我可以为条带颜色添加一个图例。知道该怎么做吗?
  • 这正是我所需要的,谢谢。但是,当我运行此代码时,构面标签不显示。
  • 我也遇到了分面标签未显示的问题。找到任何解决方案了吗?
【解决方案2】:

您可以找到此问题的更新答案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)

【讨论】:

    【解决方案3】:

    我很想知道如何做到这一点,这是个好主意。一个想法是用不同的颜色独立生成每个图表,然后使用多图或视口之类的东西并排显示 - 这需要更多的工作。

    如果您想提取此方法所需的图例 - 这是我不久前发现的 Hadley 的一些代码

    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 中提取出来的,然后我把它从图中取出 图例

    然后你最终绘制它

    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)
    

    祝你好运

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-03-25
        • 2015-02-15
        • 1970-01-01
        • 1970-01-01
        • 2019-11-27
        • 2016-07-26
        • 2021-02-05
        相关资源
        最近更新 更多