Can I plot multiple function curves in a single plot using ggplot() in a user-defined function?

Viewed 266

I am trying to build a user-defined function which basically returns a ggplot of multiple function curves in a single plot. The plot will be a complex version of the plot below:

library(ggplot2)
 p <- ggplot() + xlim(0,4) + xlab("x")
 p <- p + geom_function(fun = function(x) 1*x)
 p <- p + geom_function(fun = function(x) 2*x)
 p <- p + geom_function(fun = function(x) 3*x)
 p <- p + geom_function(fun = function(x) 4*x)
 p

Unfortunately, I am not being able to plot it using a user defined function as below. It only returns me the last plot:

plot_func <- function(i) {
   p <- ggplot() + xlim(0,i) + xlab("x")
   for (i in 1:i) {
     p <- p + geom_function(fun = function(x) i*x)
   }
   print(p)
 }
plot_func(4)

Can anyone please tell me how to plot this using a user-defined function? Thank you very much!!

2 Answers

1) Add an i argument to the function and specify it in args= like this:

library(ggplot2)
plot_func1 <- function(i) {
   p <- ggplot() + xlim(0,i) + xlab("x")
   for (i in 1:i) {
     p <- p + 
        geom_function(fun = function(x, i) i*x, args = list(i = i))
   }
   print(p)
 }
plot_func1(4)

2) or use bquote:

library(ggplot2)
plot_func2 <- function(i) {
   p <- ggplot() + xlim(0,i) + xlab("x")
   for (i in 1:i) {
     p <- p + geom_function(fun = bquote(function(x) .(i)*x))
   }
   print(p)
 }
plot_func2(4)

3) or substitute i into the function like this:

library(ggplot2)
plot_func3 <- function(i) {
   p <- ggplot() + xlim(0,i) + xlab("x")
   for (i in 1:i) {
     p <- p + geom_function(fun = substitute(function(x) i*x, list(i = i)))
   }
   print(p)
 }
plot_func3(4)

4) or define the function as a character string with i substituted in and then parse it and convert it to a call object using [[1]]:

library(ggplot2)
plot_func4 <- function(i) {
   p <- ggplot() + xlim(0,i) + xlab("x")
   for (i in 1:i) {
     p <- p + 
        geom_function(fun = parse(text = sprintf("function(x) %d*x", i))[[1]])
   }
   print(p)
 }
plot_func4(4)

Consider the functional form of running ggplots by calling its + (via undocumented +.gg() method) inside Reduce on list of aesthetic layers:

plot_func <- function(i) {
  layers <- list(ggplot(), 
                 xlim(0, i),  
                 xlab("x"),
                 lapply(1:i, function(i) geom_function(fun = function(x) i*x)))
  
  p <- Reduce(ggplot2:::`+.gg`, layers)
  print(p)
}

plot_func(4)
Related