Ggplot2: цвет полосы facet_wrap на основе переменной в наборе данных
Есть ли способ заполнить полосы фасетов, созданных 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"))
![facet_wrap and orange strip color]()
Есть ли способ передать значения в переменной size
в MYdata
параметру fill
в element_rect
?
В принципе, вместо 1 цвета для всех полосок я хотел бы, чтобы цвет фона полосы мелких фруктов (яблоко, слива, груша) был зеленым, а цвет фона больших фруктов (оранжевый, банановый, виноградный) был красным.
Ответы
Ответ 1
С небольшим количеством работы вы можете комбинировать свой сюжет с манекеном, который имеет правильные грызуны,
![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)
Ответ 2
Я хотел бы знать, как это сделать, это отличная идея. Одна идея состоит в том, чтобы генерировать каждый график независимо с другим цветом, как вы, а затем использовать что-то вроде мультиплексора или видовых экранов, чтобы показывать тогда бок о бок - для этого потребуется немного больше работы.
если вы хотите извлечь легенду, которая вам понадобится для этого подхода - вот какой-то код из Хэдли, который я нашел некоторое время назад
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, а затем я вынул его из графика legend < - g_legend (p) lwidth < - sum (легенда $width) #, если вы хотите определить окно просмотра на основе этого p < - p + theme (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)
Удачи.