at.
at.

Reputation: 52540

ggplot scale_x_log10() with bigger base than 10 for the logarithm

Is there an easy way to scale a ggplot by log base 20 or higher? This works great:

ggplot(data, aes(x, y)) + geom_line() + scale_x_log10()

Unfortunately base 10 too small. There's a more general scale_x_continuous function that takes a trans argument, but there doesn't appear to be any log transforms higher than base 10.

Upvotes: 2

Views: 1063

Answers (2)

J Thompson
J Thompson

Reputation: 164

The scales package provides transforms to the scale_x_continuous() function. You can either use the built-in flexible log transform or create your own using the trans_new() function.

Built-in with base-20:

require(scales)
base=20
p1 <- ggplot(mpg, aes(displ, hwy)) +
  geom_point()
p1 + scale_y_continuous(trans = scales::log_trans(base))

Make your own transform:

require(scales)
logTrans <- function(base=20){
  trans_new(name='logT',
          transform=function(y){
            return(log(y, base=base))
          },
          inverse=function(y){
            return(base^y)
          })
}

base=20
p1 + scale_y_p1 <- ggplot(mpg, aes(displ, hwy)) +
  geom_point()
p1 + continuous(trans = logTrans(base=base))

Upvotes: 3

Allan Cameron
Allan Cameron

Reputation: 173858

Here's a worked example of creating a new trans object to use in your plot:

Initial plot

library(ggplot2)

df <- data.frame(x = 1:10, y = 10^(1:10))

p <- ggplot(df, aes(x, y)) + geom_line()

p

With log scale using base 100

p +  scale_y_continuous(trans = scales::trans_new(name = "log100",
                        transform = function(x) log(x, 100),
                        inverse = function(x) 100^x,
                        domain = c(1e-16, Inf)),
                        breaks = scales::breaks_log(5, 100),
                        labels = scales::comma)

enter image description here

Created on 2020-12-07 by the reprex package (v0.3.0)

Upvotes: 3

Related Questions