diff --git a/R/tinytheme.R b/R/tinytheme.R index 556a8230..13426246 100644 --- a/R/tinytheme.R +++ b/R/tinytheme.R @@ -240,6 +240,14 @@ tinytheme = function( settings[[n]] = dots[[n]] } + # `col.default` < 0 gotcha for user-supplied palettes.(#627) + if ("palette.qualitative" %in% names(dots) && + !("col.default" %in% names(dots)) && + is.numeric(settings[["col.default"]]) && + settings[["col.default"]] < 0L) { + settings[["col.default"]] = abs(settings[["col.default"]]) + } + # Compute mgp from spacing primitives when dynmar is active and the user # didn't provide an explicit mgp override. The near edge of margin text # (facing the plot region) aligns with the half-cell boundary (0.5*cex from diff --git a/inst/tinytest/test-tinytheme.R b/inst/tinytest/test-tinytheme.R index 7c6491e0..26d87bb7 100644 --- a/inst/tinytest/test-tinytheme.R +++ b/inst/tinytest/test-tinytheme.R @@ -238,3 +238,14 @@ f = function () { theme = list("clean", palette.qualitative = pal, pch = 21)) } expect_snapshot_plot(f, label = "tinytheme_ephemeral_palette_function_qualitative") + + +# User palette override should not be trimmed by a theme's negative +# col.default (e.g. bw's -1), which would silently recycle colours. (#627) +f = function() { + plt( + Sepal.Length ~ Petal.Length | Species, iris, + theme = list("bw", palette.qualitative = c("red", "blue", "green")) + ) +} +expect_silent(f())