我试图使用ggplot2包在同一个图上绘制5个函数和5个数据点。当我只是绘制函数时,代码可以工作,但是只要我添加数据点,处理就需要很长时间。如果我只添加一个点, - 大约需要10分钟来绘制,并且一旦我添加超过3个点就会冻结。
下面显示了一个可重现的示例(抱歉冗长的代码,但在我的情况下,我需要集成分段函数,我希望这可能是它需要这么长时间的部分原因):
rm(list=ls())
library(ggplot2)
library(reshape2)
library(mosaic)
#Input x-values
T1 <- 3*24*3600
T2 <- 5*24*3600
T3 <- 15*24*3600
T4 <- 61*24*3600
#Input functions
V1=makeFun(75*exp(-x/50000)~x)
V2=makeFun(1000*exp(-x/60000)~x)
V3=makeFun(100*exp(-x/275000)~x)
V4=makeFun(125*exp(-(x-1300000)/800000)~x)
f1=makeFun(V1(x)+V2(x)+V3(x)~x)
f2=makeFun(V2(x)+V3(x)~x)
f3=makeFun(V3(x)~x)
f4=makeFun(V4(x)~x)
#4 piecewise functions
v <- function(x)
(integrate(function(x)
(x > 0 & x <= T1)*f1(x)/1000000000 + (x > T1 & x <= T2)*f2(x)/1000000000 + (x > T2 & x <= T3)*f3(x)/1000000000+ (x > T3 & x <= T4)*f4(x)/1000000000
, lower=0, upper=x)$value)
Vo0<- Vectorize(v)
v_w <- function(x)
(integrate(function(x)
(x >= 0 & x <= T1)*V1(x)/1000000000
, lower=0, upper=x)$value)
Vo1<- Vectorize(v_w)
v_s <- function(x)
(integrate(function(x)
(x >= 0 & x <= T2)*V2(x)/1000000000
, lower=0, upper=x)$value)
Vo2 <- Vectorize(v_s)
v_n1 <- function(x)
(integrate(function(x)
(x >= 0 & x <= T3)*V3(x)/1000000000
, lower=0, upper=x)$value)
Vo3 <- Vectorize(v_n1)
v_l <- function(x)
(integrate(function(x)
(x > T3 & x <= T4)*V4(x)/1000000000
, lower=0, upper=x)$value)
Vo4 <- Vectorize(v_l)
#Point1
x1<- 61*24*3600
y1 <- 0.205139861
# Point2
x2 <- 3*24*3600
y2 <- 0.004566857
#Point3
x3 <- 5*24*3600
y3 <- 0.062331177
#Point4
x4 <- 15*24*3600
y4<- 0.031999923
#Point5
x5 <- 46*24*3600
y5 <- 0.10585637
#Input values needed to make the ggplot
x <-(0:T4)
d <- 3600*24
p2 <- ggplot(data.frame(x = c(0:T4)), aes(x = x)) +
stat_function(fun=Vo0, size=1.5)+
stat_function(fun=Vo1, color= "blue")+
stat_function(fun=Vo2, color= "red")+
stat_function(fun=Vo3, color= "green")+
stat_function(fun=Vo4, color= "orange")+
scale_x_continuous(sec.axis = sec_axis(~./(d), name="Days [d]"))+
labs(x=expression("Seconds [s]"))+
labs(y=expression("Volume [km3]")) +
theme_bw(base_family = "Times", base_size = 18) +
theme(plot.title = element_text(hjust=0.5))
print(p2)
p3 <- p2 + geom_point(aes(x1,y1), size=3, color="black")
# geom_point(aes(x2,y2), size=1.5, color="blue")+
# geom_point(aes(x3,y3), size=1.5, color="red")+
# geom_point(aes(x4,y4), size=1.5, color="green")+
# geom_point(aes(x5,v5), size=1.5, color="orange")
print(p3)
打印p2不会花太长时间,但是当你尝试打印p3时,我的电脑上需要10分钟(OS X 10.9.5),如果我从最后4点中删除#,则只是冻结。
所以我的问题基本上是:我如何重写代码,使用ggplot2在同一个图中绘制函数(类似于我的)和数据点(多个)? 任何建议都会受到高度赞赏,因为我已经坚持了一个星期了。 谢谢你的帮助!
答案 0 :(得分:2)
将您的积分放在数据框中。如果你试图直接从全球环境中调用这些点,就像你一样,它会一遍又一遍地绘制它们。例如,对于您调用的原始数据框的每一行,它尝试在 x1 = 61 * 24 * 3600和 y1 = 0.205139861处绘制一次点ggplot
,即61 * 24 * 3600行。难怪它需要永远。
df.points <- data.frame(xs = c(x1, x2, x3, x4, x5),
ys = c(y1, y2, y3, y4, y5),
ids = paste0("Vo", 0:4))
p2 + geom_point(data = df.points, aes(xs, ys, color = ids), size=3) +
scale_color_manual(values = c("black", "blue", "red", "green", "orange"))
虽然您正在使用它,但没有理由让您的初始数据帧为61 * 24 * 3600行。 stat_function
选择一系列平滑点来评估函数,只要它知道你想要的x值的范围,它就不需要那种分辨率。将第一个ggplot
来电替换为:
p2 <- ggplot(data.frame(x = seq(0, T4, length.out = 100)), aes(x = x)) + ...
这将大大提高速度。
这些更改会在不到10秒的时间内打印出来。