4

I'm interested in plotting multiple functions in ggplot2 using stat_function. I have tried the solutions suggested here and here, but I continue to only get one function in my final figure. Overall, I want multiple quadratic functions, each spanning different lengths on the x-axis, and each in the color specified in the color column.

Here is a quick example of the data, with three quadratic functions:

intercept <- c(0.23, 0.53, 0.41)
linear <- c(0.02, 0.05, 0.04)
quad <- c(-0.01, 0.01, 0.01)
limit <- c(5, 18, 27)
color <- c('#1400E5', '#800C74', '#EC1804')
data <- data.frame(intercept, linear, quad, limit, color)

Here is the first thing I tried, which only outputs the final function in the figure:

p <- ggplot(data=data.frame(x=c(0,0))) +
  ylim(c(0,1)) +
  xlim(c(0,28))

for (i in 1:length(data$quad))
  p <- p + stat_function(aes(y=0), fun=function(x) data[i,'quad']*x^2 + data[i,'linear']*x + data[i,'intercept'], xlim=c(0, data[i,'limit']), colour=data[i,'color'])

print(p)

The result is the warning: Warning messages: 1: Removed 68 rows containing missing values (geom_path). 2: Removed 79 rows containing missing values (geom_path).

Here is the second thing I tried, which also only outputs the final function in the figure:

lines <- alply(data, 1, function(row) { 
  stat_function(fun=function(x) row['quad'] * x^2 + row['linear'] * x + row['intercept'], xlim=c(0,row['limit']), color=row['color'])  
})

ggplot(data=data.frame(x=c(0,0))) +
  lines +
  scale_y_continuous(limits=c(0,1)) +
  scale_x_continuous(limits=c(0,28))

The result is the warning: Warning messages: 1: Computation failed in stat_function(): default method not implemented for type 'list' 2: Computation failed in stat_function(): default method not implemented for type 'list' 3: Computation failed in stat_function(): default method not implemented for type 'list'

I've also tried making the dataframe into a matrix in the alply step, which produced a different error, but still didn't work.

Any advice would be appreciated. Thanks!

2
  • I came across the same problem: It looks like that using stat_function in a loop with the variable of the loop as an argument to the function always produces n functions with the last value of the loop variable. Commented Aug 6, 2018 at 8:54
  • I now found out that using the loop variable as an argument in the args argument in stat_function works, while using it as an argument in fun does not. Commented Aug 6, 2018 at 9:52

1 Answer 1

1

I can see this is an old question. As of Sep 2019, I tried to ran the code and found stat_functions when overlayed with a for loop, can only plot the last one.

Suggestions including starting from scratch with simulated data and such. I am still confused as to why this cannot be done. However, using tidy evaluation methods, I am able to solve the problem for myself and would like to present it below.

Basically writing up the many layers were tedious error-prone, so we just want to construct the ggplot2 commands expressions programmatically.

library(tidyverse)
library(rlang)

intercept <- c(0.23, 0.53, 0.41)
linear <- c(0.02, 0.05, 0.04)
quad <- c(-0.01, 0.01, 0.01)
limit <- c(5, 18, 27)
color <- c('#1400E5', '#800C74', '#EC1804')
data <- data.frame(intercept, linear, quad, limit, color)

p <- expr(ggplot(data=data.frame(x=c(0,0))) +
  ylim(c(0,1)) +
  xlim(c(0,28)))

for (i in 1:length(data$quad)){
  new_layer <- expr(
    stat_function(
      aes(y=0), 
      fun=function(x) data[!!i,'quad']*x^2 + data[!!i,'linear']*x + data[!!i,'intercept'], 
      xlim=c(0, data[!!i,'limit']), 
      colour=data[!!i,'color'])
    )
  p <- expr(!!p + !!new_layer)
}

eval(p)
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.