【问题标题】:Multiple colors in a facet STRIP background刻面 STRIP 背景中的多种颜色
【发布时间】:2014-06-11 18:07:21
【问题描述】:

我想根据组修改构面背景的颜色。我不确定这是否可能。具体来说,我正在使用具有多个层的facet_grid(不是facet_wrap)。

## Sample data
dat <- mtcars
## Add in some colors based on the data
dat$facet_fill_color <- c("red", "green", "blue", "yellow", "orange")[dat$gear]

## Create main plot
library(ggplot2)
P <- ggplot(dat, aes(x=cyl, y=wt)) + geom_point(aes(fill=hp)) + facet_grid(gear+carb ~ .)

## I can easily cahnge the background using: 
P + theme(strip.background = element_rect(fill="red"))

但是,我想为不同的组更改不同的颜色。 理想情况下,如下所示(当然不起作用)

P + theme(strip.background = element_rect(fill=dat$facet_fill_color))
P + theme(strip.background = element_rect(aes(fill=facet_fill_color)))

刻面背景可以有不止一种颜色吗?

(与上述相关,但不是实际答案:ggplot2: facet_wrap strip color based on variable in data set

【问题讨论】:

  • 您可能会发现 this answer 和链接的答案很有用。

标签: r ggplot2 facet


【解决方案1】:

就其价值而言,改编之前的gtable hack 非常简单。

## Sample data
require(ggplot2)
dat <- mtcars
## Add in some colors based on the data
dat$facet_fill_color <- c("red", "green", "blue", "yellow", "orange")[dat$gear]

## Create main plot
p <- ggplot(dat, aes(x=cyl, y=wt)) + 
  geom_point(aes(fill=hp)) + facet_grid(gear+carb ~ .) +
  theme(strip.background=element_blank())

dummy <- p
dummy$layers <- NULL
dummy <- dummy + geom_rect(data=dat, xmin=-Inf, ymin=-Inf, xmax=Inf, ymax=Inf,
                           aes(fill = facet_fill_color))

library(gtable)

g1 <- ggplotGrob(p)
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-right", g2$layout$name)
g2$grobs[strips] <- replicate(sum(strips), nullGrob(), simplify = FALSE)
g2$layout$l[panels] <- g2$layout$l[panels] + 1
g2$layout$r[panels] <- g2$layout$r[panels] + 2

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

【讨论】:

  • 哦。 SO 好多了。 +10。
【解决方案2】:

这感觉像是一件可怕的骇人听闻的事情(以至于我几乎不好意思将其发布为答案),但有可能......

require(ggplot2);require(grid)

# Facet strip colours
cols <- rep( c("red", "green", "blue", "yellow", "orange")[rep( c(4,3,5),times=c(4,3,4))] , 2 )

# Make a grob object
Pg <- ggplotGrob(P)

# To keep track of strip.background grobs
idx <- 0 

# Find each strip.background and alter its backround colour...
for( g in 1:length(Pg$grobs) ){
    if( grepl( "strip.absoluteGrob" , Pg$grobs[[g]]$name ) ){
        idx <- idx + 1
        sb <- which( grepl( "strip\\.background" , names( Pg$grobs[[g]]$children ) ) )
        Pg$grobs[[g]]$children[[sb]][]$gp$fill <- cols[idx]

    }
}

# Plot
grid.newpage()
grid.draw(Pg)

【讨论】:

    【解决方案3】:

    受@SimonO'Hanlon 的解决方案启发的替代搜索和替换策略,

    strips <- grep(pattern="strip-right", Pg$layout$name)
    
    refill <- function(strip, colour){
      strip[["children"]][[1]][["gp"]][["fill"]] <- colour
      strip
    }
    cols <- rep_len(rep.int(c("blue", "green", "red"), c(4,3,4)), length(strips))
    Pg$grobs[strips] <- mapply(refill, 
                               strip = Pg$grobs[strips], 
                               colour = cols,
                               SIMPLIFY = FALSE)
    
    grid.newpage()
    grid.draw(Pg)
    

    【讨论】:

    • baptiste - @ 句柄仅适用于 cmets 和聊天!你很幸运我回来看到这个。 +1。还是比我的好。
    • 这是同一个想法的变体,所以我想你可能想在你的答案中插入它。随你喜欢,由你决定。
    • 我认为拥有自己的答案槽已经足够不同和有用了。我喜欢这两个并且会使用它们(当需要时我必须做一些与我的解决方案类似的事情 - 但通常在pch=21 点周围设置边框宽度 - 轮廓宽度在 ggplot2 中无法设置,并且与我的点大小一起缩放不喜欢)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-29
    • 1970-01-01
    • 2015-11-18
    • 1970-01-01
    • 1970-01-01
    • 2017-02-26
    相关资源
    最近更新 更多