tidyverse / ggplot2

An implementation of the Grammar of Graphics in R
https://ggplot2.tidyverse.org
Other
6.4k stars 2k forks source link

Error when using scales::breaks_extended() in minor_breaks: "the condition has length > 1" #5844

Closed rikivillalba closed 3 months ago

rikivillalba commented 3 months ago

I get an error trying to use scales::breaks_extended():

Error in if (k >= m) 2 - (k - 1)/(m - 1) else 1: the condition has length > 1

Here is the code:

library(ggplot2)
data(mtcars)

ebreak <- scales::breaks_extended()   # devuelve closure
ggplot(mtcars, aes(mpg, cyl)) + 
  geom_point() +
  scale_x_continuous(minor_breaks = ebreak)
#> Error in if (k >= m) 2 - (k - 1)/(m - 1) else 1: the condition has length > 1

I attach the traceback. For case i can trace it to [16]. break_fun (the closure obtained from scales::breaks_extended()) pass the second arg it receives to labeling::extended "m", but it expects a single value. Instead, transformation$inverse(b) is a vector.

18: .density.max(k, m) 17: labeling::extended(rng[1], rng[2], n, ...) 16: break_fun(transformation$inverse(limits), transformation$inverse(b)) 15: get_breaks_minor(..., self = self) 14: scale$get_breaks_minor(b = breaks, limits = continuous_scale_sorted) 13: view_scale_primary(scale, limits, continuous_range) 12: view_scales_from_scale(scale_x, self$limits$x, self$expand) 11: setup_panel_params(..., self = self) 10: self$coord$setup_panel_params(scale_x, scale_y, params = self$coord_params) 9: (function (scale_x, scale_y) { self$coord$setup_panel_params(scale_x, scale_y, params = self$coord_params) })(dots[[1L]][[1L]], dots[[2L]][[1L]]) 8: mapply(FUN = f, ..., SIMPLIFY = FALSE) 7: Map(setup_panel_params, scales_x, scales_y) 6: setup_panel_params(..., self = self) 5: layout$setup_panel_params() 4: ggplot_build.ggplot(x) 3: ggplot_build(x) 2: print.ggplot(x) 1: (function (x, ...)

Package versions: ggplot2_3.5.0 scales_1.3.0 labeling_0.4.3

Tested in windows11 (R4.3.3) and ubuntu (R4.3.1)

teunbrand commented 3 months ago

Per ?continuous_scale:

When the function has two arguments, it will be given the limits and major breaks.

Your ebreak() function accepts the limits and the desired number of breaks, so it will not work.

rikivillalba commented 3 months ago

You're alrigth. the manpages of scale_x_continuous says that accepts a function that given limits will return breaks, both in "breaks" and "minor_breaks", but in minor_breaks it makes that reservation, so closing.

rikivillalba commented 3 months ago

(perhaps an affordable error message should be delivered in scales or labeling.