Как построить простую вертикальную линию с помощью abline () в R? - PullRequest
2 голосов
/ 03 июля 2019

Я не могу добавить вертикальную или горизонтальную линию к моему графику. Я чувствую, что упускаю что-то очень простое, но я не могу найти это. Я скопировал несколько примеров из интернета, но это не сработает. Что я делаю не так?

Вот что я пытаюсь:

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 ]

2 голосов
/ 04 июля 2019

В качестве альтернативы нам придется использовать xts::addEventLines.

В феврале 2015 года на 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"))) .

2 голосов
/ 03 июля 2019

Это, вероятно, должно быть выдано в CRAN. (Это уже было выдано в github , решение опубликовано в другом ответе .)

Вот обходной путь.

После этого ответа мы могли бы построить вертикальную константу скорее с lines, чем с abline. plot.xts, который используется при построении объекта "xtx", кажется, что он написан с некоторой ошибкой или неаккуратностью, так как он также сигнализирует о наличии комментария в связанном ответе и предлагает вместо этого использовать zoo::plot.zoo.

Из другого ответа мы узнаем, что мы можем использовать .index() для извлечения индексов, которые находятся ниже данных, аналогично факторам, где значения лежат ниже меток.

Однако plot.zoo сокращает даты в соответствии с неизвестным алгоритмом сглаживания (который, вероятно, можно выяснить, если внимательно изучить zoo::plot.zoo), и наша дата, которую мы строим, может попасть именно в такую ​​"черную дыру". Одним из возможных решений является дать plot.zoo a 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)
}

, который первым извлекает даты из числовых индексов. Затем он создает последовательность дат, содержащую дату, которая должна быть нанесена где-то внутри. Обратите внимание на параметры настройки tadj и ladj, поскольку впоследствии потребуется некоторая подстройка. (Вероятно, сама функция нуждается в дальнейшей доработке!) В конце концов, функция выдает батарею 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)))

Я вручную настраивал параметры tadj и ladj, пока в нужном месте не появилась только одна вертикальная линия. Это привело к сюжету ниже.

enter image description here

Примечание: К сожалению, я не смог заставить его работать с данными FTSE. Но в принципе, как видно, это работает, и вместо того, чтобы удалить мой код, я поместил его здесь.

2 голосов
/ 03 июля 2019

Это интересный вопрос.Вот мой обходной путь.Я взял индекс строки и превратил их в столбец, затем перевел график в 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"))

0 голосов
/ 03 июля 2019

Вы хотите использовать аргумент 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")
...