I want to shade different areas under a curve with different colors. Trying a vectorized version or a for() loop did not work in this case (it worked with plotting the accompanying annotation, not shown here).
Instead of the syntax of the six function calls shown below, I used the line
highlight_area(tib, 1:6)
and got the following error message:
Error in `ggplot2::geom_area()`:
! Problem while setting up geom aesthetics.
ℹ Error occurred in the 2nd layer.
Caused by error in `check_aesthetics()`:
! Aesthetics must be either length 1 or the same as the data (3003)
✖ Fix the following mappings: `fill`
Here is my Reprex:
library(ggplot2)
library(dplyr)
#>
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#>
#> filter, lag
#> The following objects are masked from 'package:base':
#>
#> intersect, setdiff, setequal, union
library(tibble)
x_lower <- seq(0.006, 0.0085, 0.0005)
x_upper <- seq(0.0065, 0.009, 0.0005)
area_colors <- c("gray90", "gray80", "gray70", "gray50", "gray40", "black")
highlight_area <- function(df, i) {
geom_area(data = df |>
filter(x >= x_lower[i] & x < x_upper[i]),
fill = area_colors[i])
}
tib <-
tibble(x = seq(0.006, 0.009, length.out = 6000),
y = dbeta(x, 300, 39700))
ggplot(tib, aes(x = x, y = y)) +
geom_line() +
highlight_area(tib, 1) +
highlight_area(tib, 2) +
highlight_area(tib, 3) +
highlight_area(tib, 4) +
highlight_area(tib, 5) +
highlight_area(tib, 6)
Created on 2023-09-26 with reprex v2.0.2
Using lapply
you could do:
library(ggplot2)
ggplot(tib, aes(x = x, y = y)) +
geom_line() +
lapply(1:6, highlight_area, df = tib)
And as a second option here is an approach which does requires any loops but instead uses cut
to bin your variable:
library(dplyr)
tib <- tib |>
mutate(
x_cut = cut(x,
breaks = seq(.006, .009, .0005),
right = FALSE, labels = area_colors
)
)
ggplot(tib, aes(x = x, y = y)) +
geom_line() +
geom_area(aes(fill = x_cut)) +
scale_fill_identity()