【问题标题】:Using geom_rect for time series shading in R在 R 中使用 geom_rect 进行时间序列着色
【发布时间】:2015-06-21 08:03:54
【问题描述】:

我正在尝试对时间序列图的某个部分进行着色(有点像衰退着色 - 类似于 this article on recession shading in excel 底部的图表)。我放了一些可能很笨拙的样本来说明。 我首先创建一个时间序列,用 ggplot2 绘制它,然后想使用 geom_rect 来提供阴影。但我的论点肯定有问题。

a<-rnorm(300)
a_ts<-ts(a, start=c(1910, 1), frequency=12)
a_time<-time(a_ts)
a_series<-ts.union(big=a_ts, month=a_time)
a_series_df<-as.data.frame(a_series)
ggplot(a_series)+
  geom_line(mapping=aes_string(x="month", y="big"))+
  geom_rect(
    fill="red",alpha=0.5, 
    mapping=aes_string(x="month", y="big"), 
    xmin=as.numeric(as.Date(c("1924-01-01"))),
    xmax=as.numeric(as.Date(c("1928-12-31"))),
    ymin=0,
    ymax=2
    )

请注意,我也尝试过,但也没有用。

geom_rect(
        fill="red",alpha=0.5, 
        mapping=aes_string(x="month", y="big"), 
        aes(
           xmin=as.numeric(as.Date(c("1924-01-01"))),
           xmax=as.numeric(as.Date(c("1928-12-31"))),
           ymin=0,
           ymax=2)
        )

【问题讨论】:

    标签: r date ggplot2 time-series


    【解决方案1】:

    使用annotate 会更容易一些,还请注意,可以指定矩形的边界,如下所示:

    ggplot(a_series_df, aes(month, big)) + 
        geom_line() +
        annotate("rect", fill = "red", alpha = 0.5, 
            xmin = 1924, xmax = 1928 + 11/12,
            ymin = -Inf, ymax = Inf) +
        xlab("time")
    

    这也可以:

    library(zoo)
    
    z <- read.zoo(a_series_df, index = 2)
    autoplot(z) + 
        annotate("rect", fill = "red", alpha = 0.5, 
            xmin = 1924, xmax = 1928 + 11/12,
            ymin = -Inf, ymax = Inf) + 
        xlab("time") +
        ylab("big")
    

    任何一个都给出这个:

    【讨论】:

    • annotate("rect",...) 是否接受边框参数?我找不到这方面的文档。我试图只得到一个只有边框的红色矩形,没有填充。
    • @urwaCFC,使用col= 而不是fill=
    • 我最终使用了 4 annotate("segment",...)。仍然感谢,我会尝试一下以备将来使用。
    • 这个答案还有一个额外的好处是可以处理不具有明确 x 和 y 映射的不寻常几何图形(例如,geom_errorbar())。
    • @Urvah,如果您使用多个注释的原因是为了获得多个阴影矩形,那么请注意 xmin 和 ymin 可以是允许使用单个注释语句的向量。例如library(ggplot2) ggplot(a_series_df, aes(month, big)) + geom_line() + annotate("rect", fill = "red", alpha = 0.5, xmin = c(1915, 1924), xmax = c(1920, 1928) + 11/12, ymin = -Inf, ymax = Inf) + xlab("time")
    【解决方案2】:

    代码工作正常,xminxmax 需要转换为十进制日期,见下文,需要 lubridate 包。

    library("lubridate")
    library("ggplot2")
    
    ggplot(a_series_df)+
      geom_line(mapping = aes_string(x = "month", y = "big")) +
      geom_rect(
        fill = "red", alpha = 0.5, 
        mapping = aes_string(x = "month", y = "big"), 
        xmin = decimal_date(as.Date(c("1924-01-01"))),
        xmax = decimal_date(as.Date(c("1928-12-31"))),
        ymin = 0,
        ymax = 2
      )
    

    更清晰的版本,首先绘制阴影,因此线条颜色不会改变。

    ggplot() +
      geom_rect(data = data.frame(xmin = decimal_date(as.Date(c("1924-01-01"))),
                                  xmax = decimal_date(as.Date(c("1928-12-31"))),
                                  ymin = -Inf,
                                  ymax = Inf),
                aes(xmin = xmin, xmax = xmax, ymin = ymin, ymax = ymax),
                fill = "grey", alpha = 0.5) +
      geom_line(data = a_series_df,aes(month, big), colour = "blue") +
      theme_classic()
    

    【讨论】:

    • 请注意,这是因为aes() 被直接传递给每个geom,而不是ggplot()。如果您将aes(x=Date,...) 提供给ggplot() 并将geom_rect() 与任何其他几何图形一起使用,则会出现奇怪的情况......
    • @Jthorpe 它是关于绘图的顺序,我可以将 aes 放在 ggplot 中并绘制线条然后绘制矩形,但线条将位于矩形后面。当然,我们可以使用 alpha。偏好。
    • 好的,具体来说,如果您将aes() 提供给ggplot(),您需要在传递给geom_rect() 的数据中提供该调用中的所有变量aes() 和字段的类必须是一致的。将aes() 的调用移动到单个geoms 比在传递给geom_rect() 的数据框中构造具有正确格式的所需变量要容易得多。
    【解决方案3】:

    要使用geom_rect,您需要通过data.frame 定义矩形坐标:

    shade = data.frame(x1=c(1918,1930), x2=c(1921,1932), y1=c(-3,-3), y2=c(4,4))
    
    #    x1   x2 y1 y2
    #1 1918 1921 -3  4
    #2 1930 1932 -3  4
    

    然后你给ggplot你的数据和阴影data.frame

    ggplot() + 
      geom_line(aes(x=month, y=big), color='red',data=a_series_df)+
      geom_rect(data=shade, 
                mapping=aes(xmin=x1, xmax=x2, ymin=y1, ymax=y2), color='grey', alpha=0.2)
    

    【讨论】:

      【解决方案4】:
      library(xts)
      library(zoo)
      library(ggts)
      

      创建一个 xts 对象

      data<-as.xts(x=runif(228,20,40),order.by = seq(as.Date("2000/01/01"), by = "month", length.out = 228))
      

      创建要为其创建阴影的日期数据框

      date<-data.frame(as.Date("2008-01-01"),as.Date("2009-01-01"))
      

      现在创建带有阴影区域的绘图

      plot_data<-ggts(data)+geom_cycle(date)
      

      【讨论】:

        猜你喜欢
        • 2016-06-21
        • 1970-01-01
        • 2021-08-24
        • 2017-04-10
        • 1970-01-01
        • 2016-10-12
        • 2021-10-31
        • 1970-01-01
        • 2019-02-10
        相关资源
        最近更新 更多