knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>",
  fig.path = "man/figures/README-",
  out.width = "100%",
  dpi = 300
)

ggbraid

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.

Installation

You can install the development version of ggbraid from GitHub with:

# install.packages("remotes")
remotes::install_github("nsgrantham/ggbraid")

Usage

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

Articles



nsgrantham/ggbraid documentation built on Jan. 6, 2023, 10:54 a.m.