Display name
Display name

Reputation: 4501

ggplot `expand_scale()` for the axes - inconsistent


Example 1

library(tidyverse)
ggplot(mtcars) +
  geom_bar(aes(x = factor(cyl))) +
  scale_y_continuous(expand = expand_scale(mult = c(0, 0)))

1

My issue seems to be that ggplot expand_scale() is not consistent in its behavior. But that statement is probably incorrect. Let's start with the plot above as our baseline and dig into this.


Example 2

If I understand the argument correctly, mult = c(X, Y) allows me the ability to expand ggplot scales X% below the plot, and Y% above the plot. That's what I get with this code below.

ggplot(mtcars) +
  geom_bar(aes(x = factor(cyl))) +
  scale_y_continuous(expand = expand_scale(mult = c(1, 0)))

2


Example 3

ggplot(mpg %>% filter(displ > 6, displ < 8), aes(displ, cty)) + 
  geom_point() + 
  facet_grid(vars(drv), vars(cyl)) + 
  geom_text(aes(label = trans)) +
  scale_x_continuous(expand = c(0, 0)) +
  coord_cartesian(clip = "off")

3

Here's the next baseline I want to work off for examples three and four.


Example 4

ggplot(mpg %>% filter(displ > 6, displ < 8), aes(displ, cty)) + 
  geom_point() + 
  facet_grid(vars(drv), vars(cyl)) + 
  geom_text(aes(label = trans)) +
  scale_x_continuous(expand = c(1, 0)) +
  coord_cartesian(clip = "off")

4

Using the same logic as in example one I'd think mult = c(X, Y) allows me the ability to expand ggplot scales X% to the left of the plot, and Y% to the right of the plot. BUT, my scale_x_continuous(expand = c(1, 0)) doesn't seem to expand the scale 1 = 100% to the left of the plot and 0 = 0% to the right of the plot.

This scale_x_continuous(expand = c(1, 0)) instead puts some extra space to the left of the plot and a lot more extra space to the right of the plot?

What is happening? Why?


Upvotes: 5

Views: 2376

Answers (1)

Z.Lin
Z.Lin

Reputation: 29095

This:

expand = c(<some number>, <some number>)

is NOT the same as this:

expand = expand_scale(mult = c(<some number>, <some number>))

From ?expand_scale, we can see the full set of default parameters for the function is this:

expand_scale(mult = 0, add = 0)

Where both mult & add can have length 1 (same value applied to lower / upper limits) or length 2 (first value applies to lower limit, second to upper).

The form expand = c(...), on the other hand, can accept a vector of either length 2 or 4. If it's a vector of length 2, the first value is mapped to mult and the second value to add, so expand = c(1, 0) is equivalent to expand = expand_scale(mult = 1, add = 0), which adds 100% expansion on both lower and upper limits. If it's a vector of length 4, the first two values are mapped to the lower limits for mult followed by add, and the last two values are mapped to the respective upper limits.

Let's use the same plot for illustration:

p <- ggplot(mpg %>% filter(displ > 6, displ < 8), aes(displ, cty)) + 
  geom_point() + 
  facet_grid(vars(drv), vars(cyl)) + 
  geom_text(aes(label = trans)) +
  coord_cartesian(clip = "off")

The following three variations will produce the same plot:

p + scale_x_continuous(expand = expand_scale(mult = 1, add = 0))
p + scale_x_continuous(expand = expand_scale(mult = 1)) # add = 0 is the default anyway
p + scale_x_continuous(expand = c(1, 0))

The following two variations will also produce the same plot. (I'm using different expansion values here for illustration, though in general, if you have 4 different expansion values to specify, the expand_scale() format is much less ambiguous than listing out all four values in a vector...)

p + scale_x_continuous(expand = expand_scale(mult = c(1, 2), add = c(3, 4)))
p + scale_x_continuous(expand = c(1, 3, 2, 4)) # note the difference in order of values

Upvotes: 6

Related Questions