Zeke - 25 days ago 8x
R Question

# Having to multiply geoms by number of facets?

I want to have multiple rectangles behind my data, but I also want to use multiple facets, every one of which these rectangles will appear in. I first ran the code below and got the error:

`Aesthetics must be either length 1 or the same as the data (12): fill`

Here's my code:

``````block_rects <- data.frame(xstart_rect=c(-0.5,  0.5,  1.5,  2.5,  3.5,  4.5),
xend_rect=c(0.5, 1.5, 2.5, 3.5, 4.5, 5.5))
df <- data.frame(xs=c(1,2,3),ys=c(1,2,3),cond=c("a","b","f"),fs=c("x","x","y"))
df %>% ggplot(aes(x=xs,y=ys,color=cond)) +
geom_rect(inherit.aes = FALSE,
data = block_rects, aes(xmin = xstart_rect, xmax = xend_rect,
ymin = -Inf, ymax = Inf),
fill = c("#f1f1f1", "white","white","white","#f1f1f1","white")) +
geom_point() +
facet_wrap(~ fs)
``````

However, I realized that when I doubled the number of items in the
`fill`
vector in
`geom_rect`
, it worked. I worked out that I had to multiply the
`fill`
vector by the number of facets the plot has (e.g. if I change
`fs`
to
`c("x","y","z")`
I need to multiple the
`fill`
column by three).

What the heck is up with that behavior? Is this a bug in the code? If not, how should I make my code so that any number of facets can be used? I don't want to have to explicitly code which variables are being faceted in
`geom_rect`
.

As you figured out, you are drawing 12 rectangles (6 rectangles in each facet). So ggplot expects either an overall fill color or a fill color identified for each of them.

An easier work-around than repeating the fill colors is to take advantage of aesthetic mapping by putting the fill colors for each rectangle into the rectangle data.frame.

``````block_rects <- data.frame(xstart_rect=c(-0.5,  0.5,  1.5,  2.5,  3.5,  4.5),
xend_rect=c(0.5, 1.5, 2.5, 3.5, 4.5, 5.5),
fill = c("#f1f1f1", "white","white","white","#f1f1f1","white"))
``````

This allows you to map `fill` to a variable within the `aes` of `geom_rect`. Use `scale_fill_identity` so it uses the given color names.

``````ggplot(df, aes(x=xs,y=ys,color=cond)) +
geom_rect(inherit.aes = FALSE,
data = block_rects, aes(xmin = xstart_rect, xmax = xend_rect,
ymin = -Inf, ymax = Inf, fill = fill)) +
geom_point() +
facet_wrap(~ fs) +
scale_fill_identity()
``````
Source (Stackoverflow)