2017-08-26 71 views
0

我试图在使用ggplot2软件包的同一图上绘制5个函数和5个数据点。当我只是绘制函数时,代码就可以工作,但只要添加数据点,处理就需要很长时间。如果我只添加一点, - 大概需要10分钟左右的绘图,并且一旦我添加超过3点,就会冻结。在r中使用ggplot2绘制多个函数和数据点的问题

重复的例子如下所示(抱歉冗长的代码,但对我来说,我需要整合分段函数,和我预期可能是为什么需要这么久的原因之一):

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个点中删除#,则r会冻结。

所以我的问题基本上是:我怎样才能重写使得可以使用GGPLOT2同积绘制功能(类似于矿)和数据点(多)的代码? 任何意见将不胜感激,因为我一直坚持这一个星期了。 感谢您的帮助!

回答

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值的范围内,它不需要那种分辨率。

p2 <- ggplot(data.frame(x = seq(0, T4, length.out = 100)), aes(x = x)) + ... 

这将大幅提高速度:替换为你的第一个ggplot电话。

enter image description here

采用这种印刷在小于10秒的那些变化。