How to make sure Y axis labels are equidistant with scale_y_log10?

Hi there!

I am trying to represent a logarithmic series using a y log scale in ggplot2, but I need the y axis labels to be equidistant. For a reason I don't understand, it seems that when the y series is 1000 or lower, the y labels are NOT equidistant, but when the y series is 10000 or higher, the y labels ARE equidistant.

Below, a couple examples with linear and logarithmic series (these are a minimal reproducible example of what I am doing. In reality, I am editing the labels to be "1 out of x", and representing the data in a heatmap).

In brief, there is any way to "force" the y axis lables to be equidistant when using scale_y_log10()?

Thanks!

library(tidyverse)

# Log series in a log scale. Y lables NOT equidistant when the series are <=1000
tibble(X = 1, Y = exp(seq(log(1), log(1000), length.out = 100))) %>% 
  ggplot(aes(X, Y)) +
  geom_point() +
  scale_y_log10(n.breaks = 10, expand = c(0,0))

# Log series in a log scale. Y lables ARE equidistant when the series are >=10000
tibble(X = 1, Y = exp(seq(log(1), log(10000), length.out = 100))) %>% 
  ggplot(aes(X, Y)) +
  geom_point() +
  scale_y_log10(n.breaks = 10, expand = c(0,0))

# Same with a linear series in a log scale
tibble(X = 1, Y = 1:10^3) %>% 
  ggplot(aes(X, Y)) +
  geom_point() +
  scale_y_log10(n.breaks = 10, expand = c(0,0))

tibble(X = 1, Y = 1:10^4) %>% 
  ggplot(aes(X, Y)) +
  geom_point() +
  scale_y_log10(n.breaks = 10, expand = c(0,0))

Created on 2021-12-13 by the reprex package (v2.0.1)

That's the nature of this vector for those values. The only "fix" I can suggest is to pad out with a dummy 10000

suppressPackageStartupMessages({
  library(ggplot2)
})

Y = c(exp(seq(log(1), log(1000), length.out = 100)),10000)

# Log series in a log scale. Y lables NOT equidistant when the series are <=1000
data.frame(X = 1, Y) |>
  ggplot(aes(X, Y)) +
  geom_point() +
  scale_y_log10(n.breaks = 10, expand = c(0,0))

Thanks to a Stack Overflow answer (r - Pretty ticks for log normal scale using ggplot2 (dynamic not manual) - Stack Overflow) I managed to get equidistant y labels in a log scale using the {scales} function trans_breaks()

Would be nice to have a simpler way to do this, but ¯\_(ツ)_/¯

library(tidyverse)
library(scales)

create_log_breaks = trans_breaks(trans = 'log10', inv = function(x) 10^x, n = 10)
breaks_y = round(create_log_breaks(1:1000), 0)

tibble(X = 1, Y = exp(seq(log(1), log(1000), length.out = 100))) %>% 
  ggplot(aes(X, Y)) +
  geom_point() +
  scale_y_log10(breaks = breaks_y, expand = c(0,0))

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.