How can you use ggplot to automatically overlay many plots of related functions?

I have a family of functions that are all the same except for one configurable parameter, and I want to plot all of these functions on one set of axes superimposed on each other. For example, it could be sin (n * x), with different values ​​for n, like 1:30, and I don't want to have to type every command every time - I suppose there must be some way to do it programmatically.

library(ggplot2)

      

define trigger functions as a function of frequency: sin (x), sin (2x), sin (3x), etc.

trigf <- function(i)(function(x)(sin(i*x)))

      

Overlay of two functional graphs - this works by hand, of course

ggplot(data.frame(x=c(0,pi)), aes(x)) + stat_function(fun=trigf(1)) +  stat_function(fun=trigf(2))

      

now try to generalize - my idea was to make a list of stat_functions using lapply

plotTrigf <- lapply(1:5, function(i)(stat_function(fun=function(x)(sin(i*x))) ))

      

try using the list items manually but it doesn't actually work - only the graph is displayed i=5

and I'm not sure why when this is not what I was referencing

ggplot(data.frame(x=c(0,pi)), aes(x)) +plotTrigf[[1]] + plotTrigf[[2]]

      

I thought this one Reduce

might handle a "sum total" to add to ggplot()

, but it doesn't work - it complains about a non-numeric argument to a binary operator

Reduce("+", plotTrigf)

      

So, I kind of got stuck doing this strategy or maybe there was another way to do it.

+3


source to share


2 answers


Are you using version R <3.2? The problem is that you really need to evaluate your parameter i

in your call lapply

. Right now, this is left as a promise and not questioned until you try to plot a plot, at which point it i

has the last meaning it had in a loop lapply

which is 5. Use:

plotTrigf <- lapply(1:5, function(i) {force(i);stat_function(fun=function(x)(sin(i*x))) })

      

You cannot just add stat_function

calls together, even without Reduce()

you get an error

stat_function(fun=sin)  + stat_function(fun=cos)
# Error in stat_function(fun = sin) + stat_function(fun = cos) : 
#   non-numeric argument to binary operator

      

You need to add them to the ggplot object. You can do it with Reduce()

if you just give the parameterinit=



Reduce("+", plotTrigf, ggplot(data.frame(x=c(0,pi)), aes(x)))

      

And in fact the special +

operator for ggplot objects allows you to add a list of objects so you don't need to at all Reduce

(see code for ggplot2:::add_ggplot

)

ggplot(data.frame(x=c(0,pi)), aes(x)) + plotTrigf

      

Final result

enter image description here

+5


source


You need to use force

to make sure the parameter is being evaluated at the right time. This is a very useful technique and a common source of confusion about loops, you should read about it in Hadley's book http://adv-r.had.co.nz/Functions.html

To solve your question: you just need to add force(i)

when defining all graphs inside the function lapply

before making the call stat_function

. Then you can use the Shrink method or any other method to combine them. Here it is possible to combine the plots with lapply

(note that I am using the operator <<-

which is discouraged)



p <- ggplot(data.frame(x=c(0,pi)), aes(x))
lapply(plotTrigf, function(x) {
  p <<- p + x
  return()
})

      

0


source







All Articles