diff --git a/NEWS.md b/NEWS.md index e6f6dca449..40e6ac725c 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,9 @@ + # ggplot2 (development version) +* Fixed bug where discrete scales could not map aesthetics only consisting of + `NA`s (#5623) + # ggplot2 3.5.0 This is a minor release that turned out quite beefy. It is focused on diff --git a/R/scale-.R b/R/scale-.R index bd80ca3ff2..2d835875b9 100644 --- a/R/scale-.R +++ b/R/scale-.R @@ -938,6 +938,9 @@ ScaleDiscrete <- ggproto("ScaleDiscrete", Scale, map = function(self, x, limits = self$get_limits()) { n <- sum(!is.na(limits)) + if (n < 1) { + return(rep(self$na.value, length(x))) + } if (!is.null(self$n.breaks.cache) && self$n.breaks.cache == n) { pal <- self$palette.cache } else { diff --git a/tests/testthat/test-scales.R b/tests/testthat/test-scales.R index 865f87d990..691f0920aa 100644 --- a/tests/testthat/test-scales.R +++ b/tests/testthat/test-scales.R @@ -716,3 +716,17 @@ test_that("Using `scale_name` prompts deprecation message", { expect_snapshot_warning(binned_scale("x", "foobar", pal_identity())) }) + +# From #5623 +test_that("Discrete scales with only NAs return `na.value`", { + + x <- c(NA, NA) + + sc <- scale_colour_discrete(na.value = "red") + sc$train(x) + expect_equal(sc$map(x), c("red", "red")) + + sc <- scale_shape(na.value = NA_real_) + sc$train(x) + expect_equal(sc$map(x), c(NA_real_, NA_real_)) +})