1

I am trying to create some ggplots automaticly. Here is my working code example for adding stat_functions:

require(ggplot2)

p1 <- ggplot(data.frame(x = c(-2.5, 7.5)), aes(x = x)) + theme_minimal()+
  stat_function(fun= function(x){1*x},lwd=1.25, colour = "navyblue") + 
  stat_function(fun= function(x){2*x},lwd=1.25, colour = "navyblue") + 
  stat_function(fun= function(x){3*-x},lwd=1.25, colour = "red")
p1

As you can see the stat_functions all use (nearly) the same function just with a different parameter. Here is what i have tried to write:

f <- function(plot,list){
  for (i in 1:length(list)){
    plot <- plot + stat_function(fun= function(x){x*list[i]})
  }
  return(plot)
}

p1 <- ggplot(data.frame(x = c(-2.5, 7.5)), aes(x = x)) + theme_minimal()

p2 <- f(p1,c(1,2,3))
p2

This however doesnt return 3 lines, but only one. Why?

6
  • OK, so what's your question? What problem have you run into? Commented Apr 26, 2021 at 14:54
  • I guess i have hidden the problem too far into the code, sry. Most of my ideas return an empty plot. I have commented as the last part of the code what happens when i execute it. I will edit my post to make it easier to see. Sorry for the inconvenience. Commented Apr 26, 2021 at 14:57
  • I notice that in custom2 you have a for loop which is overwriting plot several times. Did you mean to write plot <- plot + stat_function(...)? Commented Apr 26, 2021 at 14:58
  • I did indead, good find! Now it shows 1 or two lines (depending on what starting parameters i give) but never more than 2 (even if i would expect 3 with the example given). It doesnt show more than one red and one blue line, even if i give him more than 2 inputs. i will edid the code to show this improvment Commented Apr 26, 2021 at 15:03
  • ... and in custom1, you create some stat_function objects, but they never get returned from the function, because they're within a for loop. Just add a return call in the appropriate place. Commented Apr 26, 2021 at 15:03

2 Answers 2

4

Keep the ggplot main object separate and create a list of additional objects, very easy for example with lapply. Add this list to your main plot as usual.

Check also https://ggplot2-book.org/programming.html

library(ggplot2)
p <- ggplot(data.frame(x = c(-2.5, 7.5)), aes(x = x)) + theme_minimal()

ls_sumfun <- lapply(1:3, function(y){
  stat_function(fun= function(x){y*x}, lwd=1.25, colour = "navyblue")
}
)

p + ls_sumfun

Created on 2021-04-26 by the reprex package (v2.0.0)

Sign up to request clarification or add additional context in comments.

Comments

0

In R, you can pass functions as arguments. You can also return functions from functions. This might make your code simpler and cleaner.

Here's an example:

p1 <- ggplot(data.frame(x = c(-2.5, 7.5)), aes(x = x))

add_stat_fun <- function (ggp, f) {
  ggp + stat_function(fun = f) 
}

make_multiply_fun <- function (multiplier) {
  force(multiplier) # not sure if this is required...
  f <- function (x) {multiplier * x}
  return(f)
}

my_funs <- lapply(1:3, make_multiply_fun)
# my_funs is now a list of functions

add_stat_fun(p1, my_funs[[1]])
add_stat_fun(p1, my_funs[[2]])
add_stat_fun(p1, my_funs[[3]])

2 Comments

Thanks for the help, but i am unsure if this is applicable to my problem. The function is the part that is different each time i call stat_function, but i don't want to write it by hand. I want to give stat_function (or any other function) a list of x-values and then it adds x number of functions to my plot. I have tried that, but it doesn't add x functions, only 1.
That's fair. I'll edit it and propose a solution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.