Axis with label = comma without showing decimals for large numbers

I have an x-axis in logscale, and I would like to display the labels without scientific notation (i.e. not 1e3, but 1,000 instead). I have always done this with label = scales::comma, but now my dataset also has very small values (0.001, for instance). Hence, when I add + scale_x_log10(label = comma), I get an x-axis where 1e-3 looks like 0.001 (as it should), but 1e3 looks like 1,000.000. I would like to remove the three decimal places, so that instead of 1,000.000 I just have 1,000. Using label = comma_format(accuracy = 1), as suggested here will make values like 0.001 look just like 0, so it’s not a valid option.

Anyone has any idea?
Here there is a reproducible example of the problem:

library(ggplot2)

X <- 10^seq(-3, 3, length.out = 50)
Y <- 100 * X/(X + 1)
Demo_data <- data.frame(X, Y)

ggplot(Demo_data, aes(x = X, y = Y)) + geom_line(size = 1.5) + 
  scale_x_log10(breaks = c(1e-3, 1e-2, 1e-1, 1, 10, 1e2, 1e3),
                label = scales::comma)

This solution does not work:

ggplot(Demo_data, aes(x = X, y = Y)) + geom_line(size = 1.5) + 
      scale_x_log10(breaks = c(1e-3, 1e-2, 1e-1, 1, 10, 1e2, 1e3),
                    label = scales::comma_format(accuracy = 1))

>Solution :

One option would be to use an ifelse to conditionally set the accuracy for values > 1 and < 1:

X <- 10^seq(-3, 3, length.out = 50)
Y <- 100 * X / (X + 1)
Demo_data <- data.frame(X, Y)

library(ggplot2)
library(scales)

ggplot(Demo_data, aes(x = X, y = Y)) +
  geom_line(size = 1.5) +
  scale_x_log10(
    breaks = c(1e-3, 1e-2, 1e-1, 1, 10, 1e2, 1e3),
    label = ~ ifelse(.x < 1, scales::comma(.x), scales::comma(.x, accuracy = 1))
  )
#> Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
#> ℹ Please use `linewidth` instead.

Leave a Reply