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.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.