【问题标题】:Problems plotting multiple functions and data points together using ggplot2 in r在 r 中使用 ggplot2 将多个函数和数据点一起绘制的问题
【发布时间】:2017-08-26 23:14:25
【问题描述】:

我正在尝试使用 ggplot2 包在同一个图上绘制 5 个函数和 5 个数据点。当我只是在绘制函数时,代码就可以工作,但是一旦我添加了数据点,就需要很长时间来处理。如果我只添加一个点 - 绘制可能需要大约 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 在同一图中绘制函数(类似于我的)和数据点(多个)? 任何建议都将受到高度赞赏,因为我已经坚持了一周。 感谢您的帮助!

【问题讨论】:

    标签: r ggplot2 piecewise


    【解决方案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 秒就打印出来了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-10
      • 2010-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多