tidyverse / ggplot2

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

guide_axis_logticks() does not coordinate with minor axis breaks? #6016

Open clauswilke opened 1 month ago

clauswilke commented 1 month ago

I was playing around with guide_axis_logticks() and was surprised to find out it has no effect on the location of the minor breaks. I'm not sure about the implementation details (probably guides and breaks are completely independent) but conceptually this feels wrong. If I have a guide that sets log-ticks then I would expect it to set minor breaks also. Alternatively, if this can't be done, then it seems to me that the correct way to achieve log ticks would be to have a simple way to generate log minor breaks and then the ticks are had for free.

library(tidyverse)

data <- tibble(x = 0:40) |>
  mutate(
    y = exp(0.08 * x + 0.1 * rnorm(length(x)))
  )

ggplot(data, aes(x, y)) +
  geom_point() +
  theme_bw() +
  scale_y_log10(guide = guide_axis_logticks())

Created on 2024-07-27 with reprex v2.0.2

I found an old issue related to this: #1949 At the time we only had annotation_logticks() and I understand an annotation is independent from the minor breaks but with the guide rewrite and more flexible axis guides I think it's worth it to at least think about a more logically consistent approach.

I don't think there is any scenario in which one would ever want log-ticks together with regular minor tick lines. They just don't go together.

teunbrand commented 1 month ago

I think you're talking about the grid lines specifically, right? The tick marks are appropriately spaced for a log10 transform. Would you expect the minor gridlines to mark every multiple of 5 (medium ticks) or at every small tick?

Conceptually, the issue with automatically adjusting the grid lines as well is that a guide cannot dictate a scale where to draw minor breaks as it is one-way traffic flowing from the scale to the guide. We could encode some manual exceptions to sync grid lines with tick marks for the log ticks, but I fear this would become messy.

clauswilke commented 1 month ago

I think you're talking about the grid lines specifically, right?

Yes.

The tick marks are appropriately spaced for a log10 transform.

Correct.

Would you expect the minor gridlines to mark every multiple of 5 (medium ticks) or at every small tick?

That's open for debate. I just think it should match in some meaningful way.

Conceptually, the issue with automatically adjusting the grid lines as well is that a guide cannot dictate a scale where to draw minor breaks as it is one-way traffic flowing from the scale to the guide.

Ok, so maybe then my feature request is to add an option for log-spacing of minor grid lines to the scale. I don't think special casing is the way to go. I think the correct design principle is always to figure out which object is in control of something and then add features there rather than elsewhere.

teunbrand commented 1 month ago

I agree it would be nice to have this simply as an option. What would be the preferred API for such a thing? One switch to both set the guide and set the minor breaks? Or a keyword for the minor breaks? A different function, i.e. scale_y_log10_fancy()?

clauswilke commented 1 month ago

I think the most logical thing would be to make it an option for the minor_breaks argument. Something as simple as minor_breaks = "logticks" would work very well I think.