Skip to content

Instantly share code, notes, and snippets.

@yutannihilation
Last active September 20, 2021 00:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yutannihilation/3d0954fe2a183c08288807215e3c9705 to your computer and use it in GitHub Desktop.
Save yutannihilation/3d0954fe2a183c08288807215e3c9705 to your computer and use it in GitHub Desktop.
Check the behaviours around manual scales (current.md: the current dev version, pr4619.md: https://github.com/tidyverse/ggplot2/pull/4619)

The case 1 and 2 of the following did not work at that time. But, then insufficient values are allowed now. So, none of the following errors now.

df <- data.frame(x = 1, y = 1:3, z = factor(c("a","b", NA), exclude = NULL))
p <- qplot(x, y, data = df, colour = z)


p1 <- p + scale_colour_manual(values = c("a" = "black")) +
  ggtitle("Case 1: Insufficient values error (as expected)")

p2 <- p + scale_colour_manual(values = c("a" = "black"), na.value = "grey") +
  ggtitle("Case 2: Insufficient values error (not as expected)")

p3 <- p + scale_colour_manual(values = c("a" = "black", "c" = "white"), na.value = "grey") +
  ggtitle('Case 3: plot with "b" points given na.value (as expected)')

patchwork::wrap_plots(p1, p2, p3, ncol = 1)

Expectation

The plot should not error when the data contains fewer values than the specified levels.

Actual

It errors.

df <- data.frame(
  x = rep(1:10, 2),
  y = rnorm(20),
  group = rep(c("B", "C"), each = 10) # no A here
)

ggplot(df, aes(x, y, colour = group)) +
  geom_point(size = 3) +
  scale_colour_manual(values = c(A = "blue", B = "green", C = "red")) +
  guides(
    color = guide_legend(
      override.aes = list(
        alpha = rep(0.6, length(unique(df$group))),
        size  = rep(6,   length(unique(df$group)))
      )
    )
  )
#> Error in `[[<-.data.frame`(`*tmp*`, i, value = c(0.6, 0.6)): replacement has 2 rows, data has 3

Expectation

The legend should show levels that don’t exist in values only when

  1. The values are factors
  2. The levels of the scales exist in the levels of the factors
  3. drop = FALSE is specified

So, only the case 3 should show the blue legend for “b”.

Actual

All the plots show the blue legend.

color_map <- list(r = "red", g = "green", b = "blue")

df <- dplyr::mutate(
  randu,
  color_key  = factor(dplyr::if_else(x > y, "r", "g")),
  color_key2 = factor(dplyr::if_else(x > y, "r", "g"), levels = c("r", "g", "b"))
)

p1 <- ggplot(df, aes(x = x, y = y, fill = color_key)) + 
  scale_fill_manual(values = color_map) +
  geom_point(shape = 21, size = 7) +
  ggtitle("Case 1: character")

p2 <- ggplot(df, aes(x = x, y = y, fill = color_key2)) + 
  scale_fill_manual(values = color_map) +
  geom_point(shape = 21, size = 7) +
  ggtitle("Case 2: factor")

p3 <- ggplot(df, aes(x = x, y = y, fill = color_key2)) + 
  scale_fill_manual(values = color_map, drop = FALSE) +
  geom_point(shape = 21, size = 7) +
  ggtitle("Case 3: factor, drop = FALSE")

patchwork::wrap_plots(p1, p2, p3, ncol = 1)

# c.f. when `limits` is beyond the range of `values`, it fails
ggplot(df, aes(x = x, y = y, fill = color_key2)) + 
  scale_fill_manual(values = color_map, drop = FALSE, limits = c("r", "g", "b", "a")) +
  geom_point(shape = 21, size = 7)
#> Error: Insufficient values in manual scale. 4 needed but only 3 provided.

Created on 2021-09-20 by the reprex package (v2.0.1)

The case 1 and 2 of the following did not work at that time. But, then insufficient values are allowed now. So, none of the following errors now.

df <- data.frame(x = 1, y = 1:3, z = factor(c("a","b", NA), exclude = NULL))
p <- qplot(x, y, data = df, colour = z)


p1 <- p + scale_colour_manual(values = c("a" = "black")) +
  ggtitle("Case 1: Insufficient values error (as expected)")

p2 <- p + scale_colour_manual(values = c("a" = "black"), na.value = "grey") +
  ggtitle("Case 2: Insufficient values error (not as expected)")

p3 <- p + scale_colour_manual(values = c("a" = "black", "c" = "white"), na.value = "grey") +
  ggtitle('Case 3: plot with "b" points given na.value (as expected)')

patchwork::wrap_plots(p1, p2, p3, ncol = 1)

Expectation

The plot should not error when the data contains fewer values than the specified levels.

Actual

It errors.

df <- data.frame(
  x = rep(1:10, 2),
  y = rnorm(20),
  group = rep(c("B", "C"), each = 10) # no A here
)

ggplot(df, aes(x, y, colour = group)) +
  geom_point(size = 3) +
  scale_colour_manual(values = c(A = "blue", B = "green", C = "red")) +
  guides(
    color = guide_legend(
      override.aes = list(
        alpha = rep(0.6, length(unique(df$group))),
        size  = rep(6,   length(unique(df$group)))
      )
    )
  )

Expectation

The legend should show levels that don’t exist in values only when

  1. The values are factors
  2. The levels of the scales exist in the levels of the factors
  3. drop = FALSE is specified

So, only the case 3 should show the blue legend for “b”.

Actual

All the plots show the blue legend.

color_map <- list(r = "red", g = "green", b = "blue")

df <- dplyr::mutate(
  randu,
  color_key  = factor(dplyr::if_else(x > y, "r", "g")),
  color_key2 = factor(dplyr::if_else(x > y, "r", "g"), levels = c("r", "g", "b"))
)

p1 <- ggplot(df, aes(x = x, y = y, fill = color_key)) + 
  scale_fill_manual(values = color_map) +
  geom_point(shape = 21, size = 7) +
  ggtitle("Case 1: character")

p2 <- ggplot(df, aes(x = x, y = y, fill = color_key2)) + 
  scale_fill_manual(values = color_map) +
  geom_point(shape = 21, size = 7) +
  ggtitle("Case 2: factor")

p3 <- ggplot(df, aes(x = x, y = y, fill = color_key2)) + 
  scale_fill_manual(values = color_map, drop = FALSE) +
  geom_point(shape = 21, size = 7) +
  ggtitle("Case 3: factor, drop = FALSE")

patchwork::wrap_plots(p1, p2, p3, ncol = 1)

# c.f. when `limits` is beyond the range of `values`, it fails
ggplot(df, aes(x = x, y = y, fill = color_key2)) + 
  scale_fill_manual(values = color_map, drop = FALSE, limits = c("r", "g", "b", "a")) +
  geom_point(shape = 21, size = 7)
#> Error: Insufficient values in manual scale. 4 needed but only 3 provided.

Created on 2021-09-20 by the reprex package (v2.0.1)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment