Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ Using date breaks/minor breaks/labels in time scales. #6282

Merged
merged 13 commits into from
Jan 28, 2025
2 changes: 2 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,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 @@
#' @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 @@
position = "bottom",
sec.axis = waiver()) {

scale_x_continuous(
sc <- datetime_scale(
ggplot_global$x_aes,
"hms",

Check warning on line 241 in R/scale-date.R

View check run for this annotation

Codecov / codecov/patch

R/scale-date.R#L239-L241

Added lines #L239 - L241 were not covered by tests
name = name,
palette = identity,

Check warning on line 243 in R/scale-date.R

View check run for this annotation

Codecov / codecov/patch

R/scale-date.R#L243

Added line #L243 was not covered by tests
breaks = breaks,
date_breaks = date_breaks,

Check warning on line 245 in R/scale-date.R

View check run for this annotation

Codecov / codecov/patch

R/scale-date.R#L245

Added line #L245 was not covered by tests
labels = labels,
date_labels = date_labels,

Check warning on line 247 in R/scale-date.R

View check run for this annotation

Codecov / codecov/patch

R/scale-date.R#L247

Added line #L247 was not covered by tests
minor_breaks = minor_breaks,
date_minor_breaks = date_minor_breaks,
guide = guide,

Check warning on line 250 in R/scale-date.R

View check run for this annotation

Codecov / codecov/patch

R/scale-date.R#L249-L250

Added lines #L249 - L250 were not covered by tests
limits = limits,
expand = expand,
oob = oob,
na.value = na.value,
guide = guide,
position = position,
transform = scales::transform_hms(),
sec.axis = sec.axis
position = position

Check warning on line 254 in R/scale-date.R

View check run for this annotation

Codecov / codecov/patch

R/scale-date.R#L254

Added line #L254 was not covered by tests
)

set_sec_axis(sec.axis, sc)

Check warning on line 257 in R/scale-date.R

View check run for this annotation

Codecov / codecov/patch

R/scale-date.R#L257

Added line #L257 was not covered by tests
}


#' @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 @@
position = "left",
sec.axis = waiver()) {

scale_y_continuous(
sc <- datetime_scale(
ggplot_global$y_aes,
"hms",

Check warning on line 280 in R/scale-date.R

View check run for this annotation

Codecov / codecov/patch

R/scale-date.R#L278-L280

Added lines #L278 - L280 were not covered by tests
name = name,
palette = identity,

Check warning on line 282 in R/scale-date.R

View check run for this annotation

Codecov / codecov/patch

R/scale-date.R#L282

Added line #L282 was not covered by tests
breaks = breaks,
date_breaks = date_breaks,

Check warning on line 284 in R/scale-date.R

View check run for this annotation

Codecov / codecov/patch

R/scale-date.R#L284

Added line #L284 was not covered by tests
labels = labels,
date_labels = date_labels,

Check warning on line 286 in R/scale-date.R

View check run for this annotation

Codecov / codecov/patch

R/scale-date.R#L286

Added line #L286 was not covered by tests
minor_breaks = minor_breaks,
date_minor_breaks = date_minor_breaks,
guide = guide,

Check warning on line 289 in R/scale-date.R

View check run for this annotation

Codecov / codecov/patch

R/scale-date.R#L288-L289

Added lines #L288 - L289 were not covered by tests
limits = limits,
expand = expand,
oob = oob,
na.value = na.value,
guide = guide,
position = position,
transform = scales::transform_hms(),
sec.axis = sec.axis
position = position

Check warning on line 293 in R/scale-date.R

View check run for this annotation

Codecov / codecov/patch

R/scale-date.R#L293

Added line #L293 was not covered by tests
)

set_sec_axis(sec.axis, sc)

Check warning on line 296 in R/scale-date.R

View check run for this annotation

Codecov / codecov/patch

R/scale-date.R#L296

Added line #L296 was not covered by tests
}

#' Date/time scale constructor
Expand Down Expand Up @@ -312,9 +328,13 @@
}
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)

Check warning on line 332 in R/scale-date.R

View check run for this annotation

Codecov / codecov/patch

R/scale-date.R#L332

Added line #L332 was not covered by tests
} else {
labels <- function(self, x) {
tz <- self$timezone %||% "UTC"
label_date(date_labels, tz)(x)
}
}
}

Expand All @@ -324,15 +344,17 @@
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
Loading