【问题标题】:R: Plot a time series with quantiles using ggplot2R:使用 ggplot2 绘制带有分位数的时间序列
【发布时间】:2011-06-14 07:39:20
【问题描述】:

我需要用 ggplot2 绘制一个时间序列。对于时间序列的每个点,我也有一些分位数,比如 0.05、0.25、0.75、0.95,即每个点有五个数据。例如:

time           quantile=0.05  quantile=0.25 quantile=0.5  quantile=0.75   quantile=0.95
00:01          623.0725       630.4353      903.8870       959.1407       1327.721
00:02          623.0944       631.3707      911.9967      1337.4564       1518.539
00:03          623.0725       630.4353      903.8870      1170.8316       1431.893
00:04          623.0725       630.4353      903.8870      1336.3212       1431.893
00:05          623.0835       631.3557      905.4220      1079.6623       1452.260
00:06          623.0835       631.3557      905.4220      1079.6623       1452.260
00:07          623.0835       631.3557      905.4220      1079.6623       1452.260
00:08          623.0780       631.3483      905.3496      1056.3719       1375.610
00:09          623.0671       630.4275      903.8839      1170.8196       1356.963
00:10          623.0507       630.0261      741.8475      1006.1208       1462.271

理想情况下,我希望将 0.5 分位数作为黑线,将其他分位数作为围绕黑线的阴影颜色间隔。最好的方法是什么?我一直在四处寻找没有运气,我找不到这样的例子,更不用说 ggplot2。

任何帮助将不胜感激。

祝你好运!

【问题讨论】:

标签: r ggplot2 time-series


【解决方案1】:

这是你想要的吗? ggplot 的诀窍是理解它需要长格式的数据。这通常意味着我们必须在准备绘图之前转换数据,通常使用melt()

在使用textConnection() 读取数据并创建一个名为dat 的对象后,您将采取以下步骤:

#Melt into long format 
dat.m <- melt(dat, id.vars = "time")

#Not necessary, but if you want different line types depending on quantile, here's how I'd do it
dat.m <- within(dat.m
  , lty <- ifelse(variable == "quantile.0.5", 1
    , ifelse(variable %in% c("quantile.0.25", "quantile.0.75"),2,3)
    )
)

#plot it
ggplot(dat.m, aes(time, value, group = variable, colour = variable, linetype = lty)) + 
  geom_line() +
  scale_colour_manual(name = "", values = c("red", "blue", "black", "blue", "red"))

给你:

再次阅读您的问题后,也许您想要中位数估计之外的阴影色带而不是线条?如果是这样,试一试。这里唯一真正的技巧是我们将group = 1 作为美学传递,这样geom_line() 将在因子/字符数据中正常运行。以前,我们按具有相同效果的变量进行分组。另请注意,我们不再使用 melted data.frame,因为在这种情况下,宽的 data.frame 非常适合我们。

ggplot(dat, aes(x = time, group = 1)) +
  geom_ribbon(aes(ymin = quantile.0.05, ymax = quantile.0.95, fill = "05%-95%"), alpha = .25) + 
  geom_ribbon(aes(ymin = quantile.0.25, ymax = quantile.0.75, fill = "25%-75%"), alpha = .25) +
  geom_line(aes(y = quantile.0.5)) +
  scale_fill_manual(name = "", values = c("25%-75%" = "red", "05%-95%" = "blue")) 

编辑:强制为预测值添加图例

我们可以使用与geom_ribbon() 层相同的方法。我们将向geom_line() 添加美学,然后使用scale_colour_manual() 设置该美学的值:

ggplot(dat, aes(x = time, group = 1)) +
  geom_ribbon(aes(ymin = quantile.0.05, ymax = quantile.0.95, fill = "05%-95%"), alpha = .25) + 
  geom_ribbon(aes(ymin = quantile.0.25, ymax = quantile.0.75, fill = "25%-75%"), alpha = .25) +
  geom_line(aes(y = quantile.0.5, colour = "Predicted")) +
  scale_fill_manual(name = "", values = c("25%-75%" = "red", "05%-95%" = "blue")) +
  scale_colour_manual(name = "", values = c("Predicted" = "black"))

可能有更有效的方法可以做到这一点,但这是我一直使用的方法,并且取得了相当大的成功。 YMMV。

【讨论】:

  • ggplot 答案就像伦敦巴士。你可以等三个小时什么都看不到,然后突然你在 6 分钟内有两个! PS。 +1
  • 听起来像几年前卢布尔雅那的公交车。 :)
  • 哇,这简直太完美了!非常感谢你!我唯一需要添加的是读取“预测值”的行的图例。我怎么能那样做?我可以将 scale_fill_manual 与其他 scale_manual 结合使用吗?再次感谢!
  • 我尝试添加scale_linetype_manual(name="", values=c("predicted" = 1))无济于事...
  • @inwit - 现在将使用一个选项更新我的答案
【解决方案2】:

假设你的 dat.frame 被称为df

最简单的ggplot 解决方案是使用boxplot geom。这给出了一条黑色中心线,中间和上部位置带有填充框。

由于您已经预先汇总了数据,因此指定stat="identity" 参数很重要:

ggplot(df, aes(x=time)) + 
    geom_boxplot(
        aes(
          lower=quantile.0.25, 
          upper=quantile.0.75,
          middle=quantile.0.5,
          ymin=quantile.0.05,
          ymax=quantile.0.95
        ), 
        stat="identity",
        fill = "cyan"
)

PS。我重新创建了您的数据,如下所示:

df <- "time           quantile=0.05  quantile=0.25 quantile=0.5  quantile=0.75   quantile=0.95
00:01          623.0725       630.4353      903.8870       959.1407       1327.721
00:02          623.0944       631.3707      911.9967      1337.4564       1518.539
00:03          623.0725       630.4353      903.8870      1170.8316       1431.893
00:04          623.0725       630.4353      903.8870      1336.3212       1431.893
00:05          623.0835       631.3557      905.4220      1079.6623       1452.260
00:06          623.0835       631.3557      905.4220      1079.6623       1452.260
00:07          623.0835       631.3557      905.4220      1079.6623       1452.260
00:08          623.0780       631.3483      905.3496      1056.3719       1375.610
00:09          623.0671       630.4275      903.8839      1170.8196       1356.963
00:10          623.0507       630.0261      741.8475      1006.1208       1462.271"

df <- read.table(textConnection(df), header=TRUE)

【讨论】:

  • 嗯 - 我们对他的问题的解释不同......在重新阅读之后,我不确定谁在正确的道路上!无论如何,很好的工作展示了如何手动创建箱线图。 +1
  • 是的,我对线条和丝带风格更感兴趣,因为我的系列很长。但无论如何,谢谢,我学到了更多东西! :)
猜你喜欢
  • 2013-01-30
  • 2021-03-17
  • 2017-03-04
  • 1970-01-01
  • 2017-10-16
  • 1970-01-01
  • 2020-08-04
  • 1970-01-01
  • 2021-05-12
相关资源
最近更新 更多