knitr::opts_chunk$set( collapse = TRUE, comment = "#>", fig.path = "man/figures/README-", out.width = "100%", dpi = 300 )
ggbraid provides a new stat, stat_braid()
, that extends the functionality of geom_ribbon()
to correctly fill the area between two alternating lines (or steps) with two different colors. ggbraid also provides a geom, geom_braid()
, that wraps geom_ribbon()
and uses stat_braid()
by default.
You can install the development version of ggbraid from GitHub with:
# install.packages("remotes") remotes::install_github("nsgrantham/ggbraid")
To demonstrate, let's generate a long dataset with two alternating series.
library(ggplot2) library(ggbraid) library(tidyr) set.seed(42) # for reproducibility n <- 21 df_long <- tibble( x = c(1:n, 1:n), y = c(rnorm(n), rnorm(n, mean = 0.5)), z = c(rep("a", n), rep("b", n)) ) df_long
And let's pivot the dataset wider so we can use it with geom_ribbon()
and geom_braid()
.
df_wide <- pivot_wider(df_long, names_from = z, values_from = y) df_wide
Now let's draw the two series as lines and fill the area between them with a single color using geom_ribbon()
.
ggplot() + geom_line(aes(x, y, linetype = z), data = df_long) + geom_ribbon(aes(x, ymin = a, ymax = b), data = df_wide, alpha = 0.2) + guides(linetype = "none")
Can we fill the area between the two lines with two different colors? One color when the solid line is above the dashed line, and a different color when the solid line is below the dashed line?
That shouldn't be hard. Let's map a < b
to the fill
aesthetic in geom_ribbon()
and...
ggplot() + geom_line(aes(x, y, linetype = z), data = df_long) + geom_ribbon(aes(x, ymin = a, ymax = b, fill = a < b), data = df_wide, alpha = 0.6) + guides(linetype = "none", fill = "none")
Chaos.
What happened? Is this a bug in geom_ribbon()
?
No, it's not a bug. The problem is that we haven't dealt with line intersections properly. I call this the Unbraided Ribbon Problem.
To fix it, replace geom_ribbon()
with geom_braid()
from ggbraid.
ggplot() + geom_line(aes(x, y, linetype = z), data = df_long) + geom_braid(aes(x, ymin = a, ymax = b, fill = a < b), data = df_wide, alpha = 0.6) + guides(linetype = "none", fill = "none")
For an introduction to ggbraid and the "Unbraided Ribbon Problem", see Average Daily Temperatures.
To learn how to use geom_braid()
with geom_step()
, see NBA Finals Game.
ggbraid supports flipped aesthetics, see US Supreme Court.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.