使用ggplot2中的stat_function绘制多个函数

时间:2016-04-30 03:53:53

标签: r ggplot2

我有兴趣使用stat_function在ggplot2中绘制多个函数。我已经尝试了建议herehere的解决方案,但我仍然只在我的最终图中得到一个函数。总的来说,我想要多个二次函数,每个函数在x轴上跨越不同的长度,每个都在颜色列中指定的颜色。

以下是数据的快速示例,具有三个二次函数:

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 <- 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)

结果是警告: 警告信息: 1:删除了包含缺失值的68行(geom_path)。 2:删除了包含缺失值的79行(geom_path)。

这是我尝试的第二件事,它也只输出图中的最终函数:

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))

结果是警告: 警告信息: 1:stat_function()中的计算失败: 默认方法未实现类型&#39; list&#39; 2:stat_function()中的计算失败: 默认方法未实现类型&#39; list&#39; 3:stat_function()中的计算失败: 默认方法未实现类型&#39; list&#39;

我还尝试将数据帧放入alply步骤中的矩阵中,这会产生不同的错误,但仍然无法正常工作。

任何建议都将不胜感激。谢谢!

1 个答案:

答案 0 :(得分:0)

我可以看到这是一个老问题。截至2019年9月,我试图运行该代码,发现stat_functions覆盖有for循环时,只能绘制最后一个。

建议包括从头开始创建模拟数据等。我仍然对为什么无法做到这一点感到困惑。但是,使用整洁的评估方法,我可以自己解决问题,并在下面介绍。

基本上写出许多层是很容易出错的,所以我们只想以编程方式构造ggplot2命令表达式。

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)