Проблемы с построением нескольких функций и точек данных вместе с использованием ggplot2 в r

Я пытаюсь построить 5 функций и 5 точек данных на одном графике, используя пакет ggplot2. Код работает, когда я просто рисую функции, но как только я добавляю точки данных, обработка занимает очень много времени. Если я добавлю только одну точку, для построения графика потребуется около 10 минут, и как только я добавлю более 3 точек, r просто зависнет.

Воспроизводимый пример показан ниже (извините за длинный код, но в моем случае мне нужно интегрировать кусочные функции, и я полагаю, что это может быть одной из причин, почему это занимает так много времени):

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, на моем компьютере (OS X 10.9.5) это занимает 10 минут, и если я удаляю # из последних 4 точек, r просто зависает.

Итак, мой вопрос в основном: как я могу переписать код, который позволяет отображать функции (похожие на мои) и точки данных (несколько) на одном графике с помощью ggplot2? Любые советы будут высоко оценены, так как я застрял с этим уже неделю. Спасибо за вашу помощь!


person Gro    schedule 26.08.2017    source источник


Ответы (1)


Поместите свои точки в фреймворк данных. Если вы попытаетесь вызвать точки непосредственно из глобальной среды, как вы это делаете, она будет рисовать их снова и снова. Например, он пытается построить точку с координатами 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 секунд.

person Brian    schedule 26.08.2017