Customizing Log Axes in ggplot2: A Guide to Consistent Breaks at Integer Powers of Ten

Understanding ggplot2 Log10 Axes and Breaks

When working with ggplot2, creating log-scale axes can be a powerful way to visualize data that exhibits exponential relationships. However, one common challenge is dealing with the breaks on these log axes.

In this article, we’ll delve into the world of ggplot2 log axes, explore the breaks function from the scales package, and discover how to create consistent breaks at integer powers of ten.

Introduction to Log Axes in ggplot2

ggplot2 provides an excellent way to create a variety of visualizations, including plots with log scales. The scale_y_log10() function allows us to specify the range and breaks for our y-axis logarithmically.

p + scale_y_log10(
    breaks = scales::trans_breaks("log10", function(x) 10^x),
    labels = scales::trans_format("log10", scales::math_format(10^.x))
)

The Problem with Non-Integer Breaks

When working with log axes, it’s common to encounter non-integer breaks. These can occur when the range of data is small enough that the logarithm doesn’t quite align with integer powers of ten.

For example, consider a dataset with values ranging from 10^(-4) to 10^1:

library(ggplot2)

# dummy data
df <- data.frame(fct = rep(c("A", "B", "C"), each = 3),
                 x = rep(1:3, 3),
                 y = 10^seq(from = -4, to = 1, length.out = 9))

ggplot(df, aes(x, y)) +
  geom_point() +
  facet_wrap(~ fct, scales = "free_y") +
  scale_y_log10(
    breaks = scales::trans_breaks("log10", function(x) 10^x),
    labels = scales::trans_format("log10", scales::math_format(10^.x))
  )

This code will produce a plot with y-axis breaks at non-integer powers of ten.

A General Purpose Solution

The breaks function from the scales package is a powerful tool for customizing log axes. However, it’s not immediately clear how to use this function to create consistent breaks at integer powers of ten.

Fortunately, there’s an approach that can help us achieve this goal.

The extended_breaks() Function

The extended_breaks() function from the scales package provides a way to specify custom break points for log axes. In particular, we’re interested in using extended_breaks(Q = c(1, 5)).

breaks = function(x) {
    brks <- extended_breaks(Q = c(1, 5))(log10(x))
    10^(brks[brks %% 1 == 0])
}

This code works by:

  • Creating a vector of break points using extended_breaks()
  • Filtering out non-integer breaks
  • Returning the filtered breaks

Customizing Break Points

The Q argument in extended_breaks() specifies the range of values for which we want to customize break points. In this case, we’re interested in breaking at integer powers of ten.

breaks = function(x) {
    brks <- extended_breaks(Q = c(1, 5))(log10(x))
    10^(brks[brks %% 1 == 0])
}

By setting Q to [1, 5], we’re effectively telling extended_breaks() to consider break points between these two values.

Applying Custom Breaks

To apply our custom breaks to a log axis, we can use the following code:

library(ggplot2)
library(scales)

# dummy data
df <- data.frame(fct = rep(c("A", "B", "C"), each = 3),
                 x = rep(1:3, 3),
                 y = 10^seq(from = -4, to = 1, length.out = 9))

ggplot(df, aes(x, y)) +
  geom_point() +
  facet_wrap(~ fct, scales = "free_y") +
  scale_y_continuous(
    trans = "log10",
    breaks = function(x) {
      brks <- extended_breaks(Q = c(1, 5))(log10(x))
      10^(brks[brks %% 1 == 0])
    },
    labels = math_format(format = log10)
  )

Conclusion

In this article, we explored the world of ggplot2 log axes and breaks. We discovered how to use the breaks function from the scales package to customize break points on logarithmic scales.

By using a combination of extended_breaks() and custom filtering, we can create consistent breaks at integer powers of ten for our y-axis logarithms.

We hope this article has provided you with valuable insights into working with log axes in ggplot2.


Last modified on 2023-06-11