Skip to content

Commit

Permalink
add key article
Browse files Browse the repository at this point in the history
  • Loading branch information
teunbrand committed Sep 9, 2024
1 parent e112394 commit e994956
Showing 1 changed file with 235 additions and 0 deletions.
235 changes: 235 additions & 0 deletions vignettes/articles/keys.Rmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
---
title: "Key information"
---

```{r, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>",
dev = "ragg_png"
)
```

```{r setup}
library(gguidance)
```

Rather than information that is key, this article will discuss information about keys.

## Keys in vanilla ggplot2

The way guides exchange information with scales is through so called 'keys'.
Keys are simply data frames that typically hold information about the aesthetic, what values they represent and how these should be displayed.
You may have already seen keys if you've used the `get_guide_data()` function before, as it can be used to retrieved a guide's key.
In the data frame below, we can see a key for the 'x' aesthetic.
It tells us the relative location of tick marks in the aesthetic's `x` column, and the numerical values they represent in the `.value` column.
How the values should be communicated to users is captured in the `.label` column.
Sometimes, keys have information about additional aesthetics, like the `y` column in the key below.

```{r}
standard <- ggplot(mpg, aes(displ, hwy)) +
geom_point(aes(shape = drv, colour = drv)) +
labs(
shape = "Drive train",
colour = "Drive train",
y = "Highway efficiency",
x = "Engine Displacement"
)
get_guide_data(standard, aesthetic = "x")
```

## Keys in gguidance

The key difference between keys in gguidance and keys in ggplot2, is that gguidance exposes users to keys.
At first, this can be an inconvenience, but it allows for a greater degree of customisation.

### Regular keys

The understand better how a typical key works, we can use `key_manual()` to manually create a key.
Usually it is sufficient to just provide the `aesthetic` argument, as the `.value` and `.label` columns automatically derive from that.

```{r}
key_manual(aesthetic = c(2, 4, 6))
```

If you want custom labels, you can set the `label` argument.
Most guides in gguidance accept a `key` argument, which will cause the guide to display the information in the key, rather than the information automatically derived from the scale.

```{r}
my_key <- key_manual(aesthetic = c(2, 4, 6), label = c("two", "four", "six"))
standard + guides(x = guide_axis_custom(key = my_key))
```

In addition, you can provide some automatic keys as keywords.
Setting `key = "minor"`, is the same as setting `key = key_minor()`.
In the same fashion many other `key_*()` functions can be used as keyword by omitting the `key_`-prefix.

```{r}
standard + guides(x = guide_axis_custom(key = "minor"))
```

Some keys don't directly return data frames, but return instructions on how these keys should interact with scales.
For example `key_auto()`, the default key for many guides in gguidance, needs to know the range in which to populate tickmarks.

```{r}
key <- key_auto()
print(key)
```

We can preview what values they'd label by letting the key absorb a scale with known limits.

```{r}
template <- scale_y_log10(limits = c(1, 1000))
key(template, "y")
```

### Ranged keys

A special type of guide you may find in gguidance are so called 'ranged' guides.
The only difference with regular guides is that they do not mark a single point for an aesthetic, but rather use a start- and end-point to mark a range of the aesthetic.
This can be convenient to annotate co-occurrances between the data you are plotting and other events.
For example, we can annotate the airtimes of TV shows in timeseries data.

```{r}
ranges <- key_range_manual(
start = as.Date(c("1985-09-14", "1993-09-16")),
end = as.Date(c("1992-05-09", "2004-05-13")),
name = c("Golden Girls", "Frasier"),
level = 1:2
)
ranges
```

Compared to a regular key, we don't have an `aesthetic` column, which is replaced by the `start` and `end` columns.
In these cases, we cannot indicate a single `.value`, but we can still use the `.label` column.
The `.level` column indicates how far we have to offset a range, so we'll display "Frasier" farther away than "Golden Girls".

```{r}
ggplot(economics, aes(date, unemploy)) +
geom_line() +
guides(x.sec = primitive_bracket(ranges))
```

There is also an 'automatic' ranged key, which attempts to find patterns in the key labels.

```{r}
plot <- ggplot(mpg, aes(interaction(drv, year), displ, fill = drv)) +
geom_boxplot() +
labs(
x = "Drive train by year",
y = "Engine displacement",
fill = "Drive train"
)
plot
```

For example an obvious pattern in the x-axis labels of the plot above is that you first have 3 entries for the 3 drive trains in 1999, followed by 3 drive trains in 2008.
By default, `key_range_auto()` tries to split the label on any non-alphanumeric character, but you give explicit split instructions by using the `sep` argument.

```{r}
# Split on literal periods
key <- key_range_auto(sep = "\\.")
plot + guides(x = primitive_bracket(key = key))
```

## Futher gimmicks

### Piping keys

The `key_manual()` and `key_range_manual()` functions have equivalents that are easy to pipe.
They are called `key_map()` and `key_range_map()` respectively, and they can replace doing the following:

```{r}
key <- key_range_manual(
start = presidential$start,
end = presidential$end,
name = presidential$name
)
```

By the following, more pipe-friendly version:

```{r}
key <- presidential |>
key_range_map(
start = start,
end = end,
name = name
)
```

Both of these keys would display as something like this:

```{r}
ggplot(economics, aes(date, unemploy)) +
geom_line() +
guides(x.sec = primitive_bracket(key))
```

### Formatting keys

In addition to having a lot of control over what the keys display, you also have control over common text formatting operations in keys.
Most key options have an `...` argument that allows many arguments to `element_text()` to be passed on to the labels.

```{r}
ggplot(mpg, aes(displ, hwy)) +
geom_point() +
guides(x = guide_axis_custom(key = key_auto(colour = "red", face = "bold")))
```

In some cases where you know the label in advance, which is almost every time one uses `key_manual()`, `key_map()` or their ranged equivalents, you can even vectorise these formatting options.

```{r}
guide <- presidential |>
key_range_map(
start = start,
end = end,
name = name,
colour = ifelse(party == "Republican", "tomato", "dodgerblue"),
face = "bold"
) |>
primitive_bracket()
ggplot(economics, aes(date, unemploy)) +
geom_line() +
guides(x.sec = guide)
```

### Forbidden keys

There are, at the time of writing, two keys that you probably shouldn't use in your code.
These are `key_sequence()` and `key_bins()`.
The hope is that mentioning their use here will prevent experimenting and subsequent frustration with these keys.
You can see that `key_sequence()` does not produce an informative axis.

```{r}
my_sequence_key <- key_sequence(n = 20)
standard +
guides(x = guide_axis_custom(key = my_sequence_key))
```

The reason for this is that this key was designed for colour gradients

```{r}
ggplot(mpg, aes(displ, hwy, colour = cty)) +
geom_point() +
scale_colour_viridis_c(
guide = gizmo_barcap(key = my_sequence_key)
)
```

Likewise, `key_bins()` was not designed for regular guides, but is specific to colour steps.

```{r}
my_bins_key <- key_bins()
ggplot(mpg, aes(displ, hwy, colour = cty)) +
geom_point() +
scale_colour_viridis_c(
guide = gizmo_stepcap(key = my_bins_key)
)
```

0 comments on commit e994956

Please sign in to comment.