如何在R中使用abline()绘制简单的垂直线?

时间:2019-07-03 17:19:23

标签: r plot time-series

我无法在图形中添加垂直线或水平线。我觉得我缺少一些非常简单的东西,但似乎找不到。我已经从互联网上复制了一些示例,但无法正常工作。我在做什么错了?

这是我正在尝试的:

library(quantmod)
getSymbols("^FTSE", src="yahoo", from=as.Date('2004-01-01'), 
           to=as.Date('2013-01-01'), periodicity="weekly")

plot(FTSE$FTSE.Close)
abline(v='2008-01-01', col="red")

我也尝试过:

abline(h = 5000, col="red")abline(h = mean(FTSE$FTSE.Close), col="red")

但是它们也不起作用。没有显示行。

我只想要一条垂直线。我正在使用RStudio。

4 个答案:

答案 0 :(得分:2)

这可能应该在CRAN上发布。 (此问题已在github上发布,解决方案已发布在other answer上。) < / p>

这是一种解决方法。

在回答this之后,我们可以绘制一个垂直常数,而不是lines而不是ablineplot.xts,当我们绘制"xtx"对象时使用,似乎写得有些杂乱无章,因为它在链接的答案中也暗示了注释,建议改用zoo::plot.zoo

我们从another的答案中学到,我们可以使用.index()来提取数据下方的索引,类似于值位于标签下方的因素。

但是,plot.zoo根据未知的平滑算法(可能可以通过深入研究zoo::plot.zoo来对日期进行修剪),而我们绘制的日期可能恰好碰到了这样的“黑洞”。一种可能的解决方案是为plot.zoo提供sapply的x坐标宽边。我已经写了一个函数genXcords

genXcords <- function(data, date, tadj=0, ladj=0) {
  idx <- as.Date(as.POSIXct(.index(data), origin="1970-01-01"))
  se <- seq(as.Date(date) - 5 - tadj, by="day", length.out=21 + ladj)
  y.crds <- .index(data)[which(min(se) < idx & idx < max(se))]
  return(y.crds)
}
首先从数字索引中提取日期的

。接下来,它将创建一个日期序列,其中包含要在其中某处绘制的日期。请注意调整参数tadjladj,因为此后将需要一些微调。 (可能必须进一步完善函数本身!)最终,该函数抛出了一组x坐标,我们可以尝试绘制它们。

现在让我们在一个示例上测试genXcords方法。

# load package
library(xts)

# get data
data(sample_matrix)
sample.xts <- as.xts(sample_matrix)

# create line data
y.cords <- genXcords(sample.xts, "2007-05-16", -6, -18)  # note the adjustment!

# plot 
zoo::plot.zoo(sample.xts[,"Close"])
invisible(sapply(y.cords, function(x) lines(x=rep(x, 100), 
                                  y=seq(0, max(sample.xts$Close) + 10, length.out=100), 
                                  col="red", lty=2, lwd=2)))

我手动调整了tadjladj参数,直到在正确的位置出现一条垂直线为止。这导致了下面的图。

enter image description here

注意: :很遗憾,我无法使用它处理FTSE数据。但是原则上,正如人们所看到的那样,它不是删除我的代码,而是放在这里。

答案 1 :(得分:2)

这是一个有趣的问题。这是我的解决方法。我将行索引放入一个列中,然后将图转换为ggplot,以便可以对图进行更多控制。让我知道代码中是否有任何歧义。

library(tidyverse)
library(quantmod)

getSymbols("^FTSE", src="yahoo", from=as.Date('2004-01-01'), 
           to=as.Date('2013-01-01'), periodicity="weekly")

FTSE %>%
  as.data.frame() %>%
  rownames_to_column("date") %>%
  mutate(date = lubridate::ymd(date)) %>%
  ggplot(aes(date,FTSE.Close ))+
  geom_line()+
  geom_vline(xintercept = as.Date('2008-01-01'), col="red")+
  scale_y_continuous(breaks = scales::pretty_breaks(6), 
                     sec.axis = sec_axis(trans = ~., breaks = scales::pretty_breaks(6)))+
  scale_x_date(date_labels = "%b %d %Y", date_breaks = "2 years")+
  ggtitle("FTSE.Close",subtitle = "2014-01-01/2012-12-27")+
  theme(axis.title = element_blank(),
        axis.line.x = element_line(colour = "black"),
        axis.ticks.x = element_line(colour = "black"),
        axis.line.y = element_blank(),
        axis.ticks.y = element_blank(),
        panel.background = element_blank(),
        panel.grid.major = element_line(colour = "gray"))

答案 2 :(得分:2)

或者,我们将不得不使用xts::addEventLines

实际上在2015年2月的issue opened at github中,abline根本无法与新的plot.xts一起使用,我们应该使用替代方法。

library(quantmod)
getSymbols("^FTSE", src="yahoo", from=as.Date('2004-01-01'), 
           to=as.Date('2013-01-01'), periodicity="weekly")

plot(FTSE$FTSE.Close)
# abline(v='2008-01-01', col="red")  # won't work

# alternative
events <- xts("", as.Date("2008-01-01"))
addEventLines(events, col="red", lwd=2)

结果

enter image description here

注意:也可以定义多个事件行,例如events <- xts(letters[1:3], as.Date(c("2008-01-01", "2009-01-01", "2010-01-01")))

答案 3 :(得分:0)

您要使用v参数(对于垂直)而不是h参数(对于水平)。这是一个可重现的示例:

d <- data.frame("y" = 1:5, 
                "dates" = paste0("2012-01-0", 1:5))

plot(d$y ~ d$dates)

abline(v = which(d$dates == "2012-01-01"), col = "red")