Skip to content

Commit

Permalink
✨ Using date breaks/minor breaks/labels in time scales. (#6282)
Browse files Browse the repository at this point in the history
* Allow `transform = "hms"` in `datetime_scale()`

* add date arguments to time scales

* use `datetime_scale()` in time scales

* allow for additional underscore args

* inherit position scale

* `label_time()` can handle both <POSIXt> *and* <difftime> classes

* add test

* add news bullet

* redocument

* work in a skip

* Revert "`label_time()` can handle both <POSIXt> *and* <difftime> classes"

This reverts commit adcd2cb.

* separate labelling logic
  • Loading branch information
teunbrand authored Jan 28, 2025
1 parent f2ad948 commit f828794
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 19 deletions.
2 changes: 2 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,8 @@
* All scales now expose the `aesthetics` parameter (@teunbrand, #5841)
* New `theme(legend.key.justification)` to control the alignment of legend keys
(@teunbrand, #3669).
* Added `scale_{x/y}_time(date_breaks, date_minor_breaks, date_labels)`
(@teunbrand, #4335).

# ggplot2 3.5.1

Expand Down
56 changes: 39 additions & 17 deletions R/scale-date.R
Original file line number Diff line number Diff line change
Expand Up @@ -223,8 +223,11 @@ scale_y_datetime <- function(name = waiver(),
#' @rdname scale_date
scale_x_time <- function(name = waiver(),
breaks = waiver(),
date_breaks = waiver(),
minor_breaks = waiver(),
date_minor_breaks = waiver(),
labels = waiver(),
date_labels = waiver(),
limits = NULL,
expand = waiver(),
oob = censor,
Expand All @@ -233,29 +236,37 @@ scale_x_time <- function(name = waiver(),
position = "bottom",
sec.axis = waiver()) {

scale_x_continuous(
sc <- datetime_scale(
ggplot_global$x_aes,
"hms",
name = name,
palette = identity,
breaks = breaks,
date_breaks = date_breaks,
labels = labels,
date_labels = date_labels,
minor_breaks = minor_breaks,
date_minor_breaks = date_minor_breaks,
guide = guide,
limits = limits,
expand = expand,
oob = oob,
na.value = na.value,
guide = guide,
position = position,
transform = scales::transform_hms(),
sec.axis = sec.axis
position = position
)

set_sec_axis(sec.axis, sc)
}


#' @rdname scale_date
#' @export
scale_y_time <- function(name = waiver(),
breaks = waiver(),
date_breaks = waiver(),
minor_breaks = waiver(),
date_minor_breaks = waiver(),
labels = waiver(),
date_labels = waiver(),
limits = NULL,
expand = waiver(),
oob = censor,
Expand All @@ -264,20 +275,25 @@ scale_y_time <- function(name = waiver(),
position = "left",
sec.axis = waiver()) {

scale_y_continuous(
sc <- datetime_scale(
ggplot_global$y_aes,
"hms",
name = name,
palette = identity,
breaks = breaks,
date_breaks = date_breaks,
labels = labels,
date_labels = date_labels,
minor_breaks = minor_breaks,
date_minor_breaks = date_minor_breaks,
guide = guide,
limits = limits,
expand = expand,
oob = oob,
na.value = na.value,
guide = guide,
position = position,
transform = scales::transform_hms(),
sec.axis = sec.axis
position = position
)

set_sec_axis(sec.axis, sc)
}

#' Date/time scale constructor
Expand Down Expand Up @@ -312,9 +328,13 @@ datetime_scale <- function(aesthetics, transform, trans = deprecated(),
}
if (!is.waiver(date_labels)) {
check_string(date_labels)
labels <- function(self, x) {
tz <- self$timezone %||% "UTC"
label_date(date_labels, tz)(x)
if (transform == "hms") {
labels <- label_time(date_labels)
} else {
labels <- function(self, x) {
tz <- self$timezone %||% "UTC"
label_date(date_labels, tz)(x)
}
}
}

Expand All @@ -324,15 +344,17 @@ datetime_scale <- function(aesthetics, transform, trans = deprecated(),
scale_class <- switch(
transform,
date = ScaleContinuousDate,
time = ScaleContinuousDatetime
time = ScaleContinuousDatetime,
ScaleContinuousPosition
)
} else {
scale_class <- ScaleContinuous
}

transform <- switch(transform,
date = transform_date(),
time = transform_time(timezone)
time = transform_time(timezone),
hms = transform_hms()
)

sc <- continuous_scale(
Expand Down
6 changes: 6 additions & 0 deletions man/scale_date.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions tests/testthat/_snaps/prohibited-functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,8 @@
[4] "date_minor_breaks"
$scale_x_time
[1] "minor_breaks"
[1] "date_breaks" "minor_breaks" "date_minor_breaks"
[4] "date_labels"
$scale_y_continuous
[1] "minor_breaks"
Expand All @@ -157,7 +158,8 @@
[4] "date_minor_breaks"
$scale_y_time
[1] "minor_breaks"
[1] "date_breaks" "minor_breaks" "date_minor_breaks"
[4] "date_labels"
$sf_transform_xy
[1] "target_crs" "source_crs" "authority_compliant"
Expand Down
14 changes: 14 additions & 0 deletions tests/testthat/test-scale-date.R
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,20 @@ test_that("not cached across calls", {
expect_equal(get_panel_scales(p2)$x$timezone, "Australia/Lord_Howe")
})

test_that("time scale date breaks and labels work", {
skip_if_not_installed("hms")

d <- c(base_time(), base_time() + 5 * 24 * 3600) - base_time()

sc <- scale_x_time(date_breaks = "1 day", date_labels = "%d")
sc$train(d)

breaks <- sc$get_breaks()
expect_length(breaks, 6)
labels <- sc$get_labels(breaks)
expect_equal(labels, paste0("0", 1:6))
})

test_that("datetime size scales work", {
p <- ggplot(df, aes(y = y)) + geom_point(aes(time1, size = time1))

Expand Down

0 comments on commit f828794

Please sign in to comment.