Skip to content

Commit 8c86d97

Browse files
authored
Fix bug in guide_axis_logticks(negative.small) (#6126)
* ensure effective limits are sorted when negatives present * smarter defaults for `negative.small` * add news bullet * add test * use `scales::minor_breaks_log()`
1 parent 109d049 commit 8c86d97

File tree

4 files changed

+19
-35
lines changed

4 files changed

+19
-35
lines changed

NEWS.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# ggplot2 (development version)
22

3+
* Better handling of the `guide_axis_logticks(negative.small)` parameter when
4+
scale limits have small maximum (@teunbrand, #6121).
5+
* Fixed bug where the `ggplot2::`-prefix did not work with `stage()`
36
* New roxygen tag `@aesthetics` that takes a Geom, Stat or Position class and
47
generates an 'Aesthetics' section.
58
* `annotation_borders()` replaces the now-deprecated `borders()`

R/guide-axis-logticks.R

Lines changed: 7 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ NULL
1717
#' keep the default `NULL` argument.
1818
#' @param negative.small When the scale limits include 0 or negative numbers,
1919
#' what should be the smallest absolute value that is marked with a tick?
20+
#' If `NULL` (default), will be the smallest of 0.1 or 0.1 times the absolute
21+
#' scale maximum.
2022
#' @param short.theme A theme [element][element_line()] for customising the
2123
#' display of the shortest ticks. Must be a line or blank element, and
2224
#' it inherits from the `axis.minor.ticks` setting for the relevant position.
@@ -69,7 +71,7 @@ guide_axis_logticks <- function(
6971
mid = 1.5,
7072
short = 0.75,
7173
prescale.base = NULL,
72-
negative.small = 0.1,
74+
negative.small = NULL,
7375
short.theme = element_line(),
7476
expanded = TRUE,
7577
cap = "none",
@@ -186,40 +188,12 @@ GuideAxisLogticks <- ggproto(
186188

187189
# Reconstruct original range
188190
limits <- transformation$inverse(scale$get_limits())
189-
has_negatives <- any(limits <= 0)
190191

191-
if (!has_negatives) {
192-
start <- floor(log10(min(limits))) - 1L
193-
end <- ceiling(log10(max(limits))) + 1L
194-
} else {
195-
params$negative_small <- params$negative_small %||% 0.1
196-
start <- floor(log10(abs(params$negative_small)))
197-
end <- ceiling(log10(max(abs(limits)))) + 1L
198-
}
192+
ticks <- minor_breaks_log(smallest = params$negative_small)(limits)
193+
tick_type <- match(attr(ticks, "detail"), c(10, 5, 1))
194+
ticks <- transformation$transform(ticks)
199195

200-
# Calculate tick marks
201-
tens <- 10^seq(start, end, by = 1)
202-
fives <- tens * 5
203-
ones <- as.vector(outer(setdiff(2:9, 5), tens))
204-
205-
if (has_negatives) {
206-
# Filter and mirror ticks around 0
207-
tens <- tens[tens >= params$negative_small]
208-
tens <- c(tens, -tens, 0)
209-
fives <- fives[fives >= params$negative_small]
210-
fives <- c(fives, -fives)
211-
ones <- ones[ones >= params$negative_small]
212-
ones <- c(ones, -ones)
213-
}
214-
215-
# Set ticks back into transformed space
216-
ticks <- transformation$transform(c(tens, fives, ones))
217-
nticks <- c(length(tens), length(fives), length(ones))
218-
219-
logkey <- data_frame0(
220-
!!aesthetic := ticks,
221-
.type = rep(1:3, times = nticks)
222-
)
196+
logkey <- data_frame0(!!aesthetic := ticks, .type = tick_type)
223197

224198
# Discard out-of-bounds ticks
225199
range <- if (params$expanded) scale$continuous_range else scale$get_limits()

man/guide_axis_logticks.Rd

Lines changed: 4 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/testthat/test-guide-axis.R

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,11 @@ test_that("guide_axis_logticks calculates appropriate ticks", {
9090
expect_equal(unlog, c(-rev(outcome), 0, outcome))
9191
expect_equal(key$.type, rep(c(1,2,3), c(7, 4, 28)))
9292

93+
# Test very small pseudo_log (#6121)
94+
scale <- test_scale(transform_pseudo_log(sigma = 1e-5), c(0, 1e-10))
95+
key <- train_guide(guide_axis_logticks(), scale)$logkey
96+
expect_gte(nrow(key), 1)
97+
9398
# Test expanded argument
9499
scale <- test_scale(transform_log10(), c(20, 900))
95100
scale$continuous_range <- c(1, 3)

0 commit comments

Comments
 (0)