在ggplot中,一个facet STRIP背景可以有多种颜色。

12

2023年更新:

现在有一个很棒的软件包,由@teunbrand开发的ggh4x
请参阅这个答案以了解相关问题


问题:在ggplot中,我们如何根据组修改facet背景的颜色?
facet背景可以有多种颜色吗?
示例:
我正在使用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 ~ .)

所有条纹的背景都可以使用以下方法进行更改:
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条纹颜色)


你可能会发现这个答案和链接的答案很有用。 - Simon O'Hanlon
4个回答

14

就我所知,很容易根据之前那个gtable hack进行调整。

enter image description here

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

4

这种做法似乎很不专业(以至于我几乎不好意思把它作为一个答案发布出去),但是它是可行的...

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)

enter image description here


4

受@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 - @符号只在评论和聊天中起作用!你很幸运我回来看到了这个。+1。还是比我的好。 - Simon O'Hanlon
这是同一思路的变体,所以我想你可能想把它插入到你的答案中。由你决定,随你喜欢。 - baptiste
我认为这个答案区别足够大且有用,值得拥有自己的答案区。我喜欢这两个方法,并会在需要时使用它们(当我需要类似于我的解决方案时 - 但通常是为了在pch = 21点周围设置边框宽度 - ggplot2中无法设置轮廓宽度并且随着点大小而缩放,我不喜欢这种方式)。 - Simon O'Hanlon

2

在类似问题ggplot2:facet_wrap strip color based on variable in data set中,有一个非常好的简单答案被埋没了,它避免了hack,尽管你仍然需要手动指定strip_themed()中想要的颜色。

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)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接