【问题标题】:How can I get the peak and valleys of a geom_smooth line in ggplot2?如何在 ggplot2 中获得 geom_smooth 线的峰值和谷值?
【发布时间】:2020-09-18 22:46:22
【问题描述】:

我正在绘制一年中的一些数据,我需要获取曲线的峰谷,而不是从数据集中,然后确定哪个是那个日期。我该怎么做?

g <- ggplot(df, aes(x=date, y=ndvitrend)) + geom_point() + geom_smooth(method = "gam", se=FALSE) + theme_minimal() +
     scale_x_date(date_labels="%b %Y", date_breaks = "1 month") + 
     theme(plot.title = element_text(hjust = 0.5)) + theme(axis.line = element_line(color = 'black')) +
     theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust=1)) + 
     stat_peaks(span=NULL, color="red")

谢谢

【问题讨论】:

    标签: r ggplot2


    【解决方案1】:

    如果我们有可重复的数据,回答这类问题会容易得多。但是,我将重新创建类似于您的数据集的内容:

    set.seed(69)
    
    df <- data.frame(date = seq(as.Date("2019-09-01"), 
                                as.Date("2020-09-01"), by = "3 days"),
                     ndvitrend = 0.3 * sin(seq(-2, 2 * pi - 2, length.out = 123)) +
                                 rnorm(123, 0.5, 0.2))
    

    现在让我们使用您的代码来绘制它:

    library(ggpmisc)
    
    g <- ggplot(df, aes(x = date, y = ndvitrend)) + 
          geom_point() + 
          geom_smooth(method = "gam", se = FALSE) + 
          stat_peaks(span = NULL, color = "red") +
          theme_minimal() +
          scale_x_date(date_labels = "%b %Y", date_breaks = "1 month") + 
          theme(plot.title  = element_text(hjust = 0.5),
                axis.line   = element_line(color = 'black'),
                axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1))
    g
    #> `geom_smooth()` using formula 'y ~ s(x, bs = "cs")'
    

    您会注意到控制台告诉我们用于创建平滑线的公式。因此,我们可以用它来回答您的问题。我们需要 mgcv 包中的 gam 函数:

    library(mgcv)
    
    df$days <- as.numeric(difftime(df$date, df$date[1], units = "day"))
    model   <- gam(ndvitrend ~ s(days, bs = "cs"), data = df)
    df$prediction <- predict(model)
    

    所以现在我们已将来自该模型的预测存储到我们的数据框中。这应该会为我们提供与geom_smooth 相同的平滑曲线:

    g + geom_line(aes(y = prediction), data = df, 
                       size = 3, linetype = 2, col = "red")
    #> `geom_smooth()` using formula 'y ~ s(x, bs = "cs")'
    

    这是正确的。现在我们需要做的就是找出我们预测的峰值在哪里:

    g + geom_hline(yintercept = max(df$prediction), linetype = 2)
    #> `geom_smooth()` using formula 'y ~ s(x, bs = "cs")'
    

    所以我们可以看到我们在这个数据集中的平滑峰值是

    max(df$prediction)
    #> [1] 0.76714
    

    它发生在:

    df$date[which.max(df$prediction)]
    #> [1] "2020-03-20"
    

    reprex package (v0.3.0) 于 2020 年 9 月 18 日创建

    【讨论】:

      猜你喜欢
      • 2013-07-29
      • 2020-06-06
      • 1970-01-01
      • 2023-03-11
      • 1970-01-01
      • 1970-01-01
      • 2021-01-13
      • 2017-12-31
      • 2018-10-15
      相关资源
      最近更新 更多