From 0284dc64075d7f8d5057a34ac0ce5474b7380a25 Mon Sep 17 00:00:00 2001 From: Vincent Arel-Bundock Date: Fri, 30 Jan 2026 11:04:51 -0500 Subject: [PATCH] issue #327 jitter dates --- NEWS.md | 5 + R/type_jitter.R | 19 +- inst/tinytest/_tinysnapshot/type_j_date.svg | 214 ++++++++++++++++++++ inst/tinytest/test-type_jitter.R | 28 +++ 4 files changed, 264 insertions(+), 2 deletions(-) create mode 100644 inst/tinytest/_tinysnapshot/type_j_date.svg create mode 100644 inst/tinytest/test-type_jitter.R diff --git a/NEWS.md b/NEWS.md index cb61f631..38663751 100644 --- a/NEWS.md +++ b/NEWS.md @@ -11,6 +11,11 @@ where the formatting is also better._ - The legend plot characters for the `"pointrange"` and `"errorbar"` types now include a line, to better resemble the actual plot elements (#533 @grantmcdermott) +### Bug fixes + +- Jittered plots now support Date/POSIXt axes. Thanks to @wachtermh for the bug + report and @vincentarelbundock for the code contribution. (#327) + ### Internals - We now encourage type-specific legend customizations within the individual diff --git a/R/type_jitter.R b/R/type_jitter.R index 85b870e7..6a2ea6f1 100644 --- a/R/type_jitter.R +++ b/R/type_jitter.R @@ -23,6 +23,21 @@ type_jitter = function(factor = 1, amount = NULL) { } +jitter_restore = function(obj, factor, amount) { + if (inherits(obj, "POSIXlt")) { + obj = as.POSIXct(obj) + } + if (inherits(obj, c("Date", "POSIXt", "yearmon", "yearqtr"))) { + obj_attrs = attributes(obj) + out = jitter(unclass(obj), factor = factor, amount = amount) + attributes(out) = obj_attrs + } else { + out = jitter(obj, factor = factor, amount = amount) + } + return(out) +} + + data_jitter = function(factor, amount) { fun = function(settings, ...) { env2env(settings, environment(), "datapoints") @@ -45,8 +60,8 @@ data_jitter = function(factor, amount) { } else { ylabs = NULL } - x = jitter(x, factor = factor, amount = amount) - y = jitter(y, factor = factor, amount = amount) + x = jitter_restore(x, factor = factor, amount = amount) + y = jitter_restore(y, factor = factor, amount = amount) datapoints$x = x datapoints$y = y diff --git a/inst/tinytest/_tinysnapshot/type_j_date.svg b/inst/tinytest/_tinysnapshot/type_j_date.svg new file mode 100644 index 00000000..aa644ff1 --- /dev/null +++ b/inst/tinytest/_tinysnapshot/type_j_date.svg @@ -0,0 +1,214 @@ + + + + + + + + + + + + + +Date +Temp + + + + + + +May +Jun +Jul +Aug +Sep + + + + + +60 +70 +80 +90 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inst/tinytest/test-type_jitter.R b/inst/tinytest/test-type_jitter.R new file mode 100644 index 00000000..a4843c2f --- /dev/null +++ b/inst/tinytest/test-type_jitter.R @@ -0,0 +1,28 @@ +source("helpers.R") +using("tinysnapshot") + +f = function() { + set.seed(42) + tinyplot(Temp ~ Month | ordered(Month), airquality, type = "j", pch = 16) +} +expect_snapshot_plot(f, label = "type_j") + +f = function() { + set.seed(42) + tinyplot(Species ~ Sepal.Length, data = iris, type = "j") +} +expect_snapshot_plot(f, label = "type_j_y") + +f = function() { + set.seed(42) + data("airquality") + airquality$Year = 1973 + airquality$Date = as.Date(paste0( + airquality$Year, + "-", + airquality$Month, + "-01" + )) + tinyplot(Temp ~ Date, data = airquality, type = "j", pch = 16) +} +expect_snapshot_plot(f, label = "type_j_date")