Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://nsgrantham.github.io/ggbraid/

Braided ribbons in ggplot2
https://nsgrantham.github.io/ggbraid/

Last synced: 3 days ago
JSON representation

Braided ribbons in ggplot2

Awesome Lists containing this project

README

        

---
output: github_document
---

```{r, include = FALSE}
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:

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

## Usage

To demonstrate, let's generate a long dataset with two alternating series.

```{r example}
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()`.

```{r pivot-wider}
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()`.

```{r geom-ribbon-without-fill}
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...

```{r geom-ribbon-with-fill}
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](https://nsgrantham.github.io/ggbraid/articles/temps.html#the-unbraided-ribbon-problem).

To fix it, replace `geom_ribbon()` with `geom_braid()` from ggbraid.

```{r geom-braid-with-fill}
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

- For an introduction to ggbraid and the "Unbraided Ribbon Problem", see [Average Daily Temperatures](https://nsgrantham.github.io/ggbraid/articles/temps.html).

- To learn how to use `geom_braid()` with `geom_step()`, see [NBA Finals Game](https://nsgrantham.github.io/ggbraid/articles/hoops.html).

- ggbraid supports flipped aesthetics, see [US Supreme Court](https://nsgrantham.github.io/ggbraid/articles/court.html).