0

is it possible to make a ggplot2 extension (ex. geom_smooth) that converts the existing xy axes into log10 scales automatically?

here's a reprex for example

set.seed(11) # generate random data
method1 = c(rnorm(19,0,1),2.5)
method2 = c(rnorm(19,0,1),2.5)
Subject <- rep(paste0('S',seq(1:20)), 2)
Data <- data.frame(Value = matrix(c(method1,method2),ncol=1))
Method <- rep(c('Method 1', 'Method 2'), each = length(method1))
df_corr <- data.frame(first = method1, second = method2) # used for correlation

ggplot(data = df_corr, mapping = aes(x = first, y = second)) +
  geom_smooth() + # line 2
  scale_x_continuous(trans = 'log10') +  # line 3
  scale_y_continuous(trans = 'log10') # line4

Instead I would like to create a ggplot2 extension function (that receives all the aesthetics defined by ggplot2()) that does what lines 2-4 at once using ggproto.

Sam Min
  • 77
  • 5
  • 1
    Can you explain why you're looking for a solution with ggproto and the suggested answers don't sufficiently address the reason why you'd like to use ggproto? – teunbrand Jun 08 '22 at 07:12
  • 1
    The reason I think the idea might require further thought, is because the core concept of the grammar of graphics, on which ggplot2 is based, is that layers like geometries should be independently defined from scales and their transformations. Joining these in a ggproto class would be confusing to anyone comfortable with ggplot2. – teunbrand Jun 08 '22 at 07:15
  • you raise a good point, I just wanted to try to it and got stuck, thanks for your thoughts – Sam Min Jun 08 '22 at 12:54

2 Answers2

2

You could also throw the three lines into a list:

geom_smooth_log <- list(
  geom_smooth(), # line 2
    scale_x_continuous(trans = 'log10'),  # line 3
    scale_y_continuous(trans = 'log10') # line4
)

ggplot(data = df_corr, mapping = aes(x = first, y = second)) +
  geom_smooth_log
Jon Spring
  • 55,165
  • 4
  • 35
  • 53
1

You can implement your own function in the following manner:

library(tidyverse)
set.seed(11) # generate random data
method1 = c(rnorm(19,0,1),2.5)
method2 = c(rnorm(19,0,1),2.5)
Subject <- rep(paste0('S',seq(1:20)), 2)
Data <- data.frame(Value = matrix(c(method1,method2),ncol=1))
Method <- rep(c('Method 1', 'Method 2'), each = length(method1))
df_corr <- data.frame(first = method1, second = method2) # used for correlation

my_log_plot <- function(data, x, y) {
  ggplot(data, aes({{x}}, {{y}})) +
    geom_smooth() +
    scale_x_log10() +
    scale_y_log10()
}

my_log_plot(df_corr, first, second)

To create your own ggplot function, you need to use ggproto, and the process is outlined here.

philiptomk
  • 768
  • 3
  • 11