在 ggplot 中绘制时间序列的问题,带有图例(股票价格)

Issues with plotting a time series in ggplot, with legends (Stock prices)

我正在尝试用指标绘制股票价格,但是我找不到如何向图中添加标签。我想我无法理解 ggplot 如何处理时间序列。我已经看到其他人使用所有数据创建了新列,但我不知道这将如何适用于此。我原本想绘制收盘价以及 50 天和 200 天移动平均线,并相应地显示一个标签。

这是没有标签的数据和图表。也欢迎提供有关 ggplot 的更多信息的任何资源。

structure(c(3.320236, 3.300589, 3.483955, 3.588736, 3.418468, 
3.497053, 3.549443, 3.582187, 3.601834, 3.588736, 1803600, 2480600, 
2608100, 2315800, 3706400, 2648200, 1851400, 1297000, 2230600, 
1667900, 4.04544857999999, 4.01964633999999, 4.00091679999999, 
3.98559263999999, 3.96987555999999, 3.95442041999999, 3.94407331999999, 
3.93791745999999, 3.92586769999999, 3.91892597999999, 4.80337260999993, 
4.79541582999993, 4.78650947499993, 4.77812702499993, 4.76981006499993, 
4.76195151999993, 4.75271772499993, 4.74482643499993, 4.73775374499993, 
4.72956775999993, 169569500, 167088900, 169697000, 172012800, 
168306400, 170954600, 172806000, 174103000, 176333600, 174665700, 
3.32023599999963, 3.30058899999973, 3.48395499999974, 3.58873599999971, 
3.41846799999982, 3.49705299999975, 3.54944299999964, 3.58218699999948, 
3.6018339999997, 3.5887359999996), class = c("xts", "zoo"), index = structure(c(1546387200, 
1546473600, 1546560000, 1546819200, 1546905600, 1546992000, 1547078400, 
1547164800, 1547424000, 1547510400), tzone = "UTC", tclass = "Date"), .Dim = c(10L, 
6L), .Dimnames = list(NULL, c("SPWR.Close", "SPWR.Volume", "SMA", 
"SMA.1", "obv", "VWAP")))
ggplot(data = df, aes(x = Date, y = Price)) + 
  geom_line(aes(y = SPWR.Close)) +
  geom_line(aes(y = SMA), col = "red") +
  geom_line(aes(y = SMA.1), col = "blue")

一种方法是将 TS 转换为数据框并将行名转换为新列。然后重新排列数据以简洁的方式绘制它

# needed libraries
library(ggplot2)
library(dplyr)
library(tidyr)
# your dummy data
df <- structure(c(3.320236, 3.300589, 3.483955, 3.588736, 3.418468, 
              3.497053, 3.549443, 3.582187, 3.601834, 3.588736, 1803600, 2480600, 
              2608100, 2315800, 3706400, 2648200, 1851400, 1297000, 2230600, 
              1667900, 4.04544857999999, 4.01964633999999, 4.00091679999999, 
              3.98559263999999, 3.96987555999999, 3.95442041999999, 3.94407331999999, 
              3.93791745999999, 3.92586769999999, 3.91892597999999, 4.80337260999993, 
              4.79541582999993, 4.78650947499993, 4.77812702499993, 4.76981006499993, 
              4.76195151999993, 4.75271772499993, 4.74482643499993, 4.73775374499993, 
              4.72956775999993, 169569500, 167088900, 169697000, 172012800, 
              168306400, 170954600, 172806000, 174103000, 176333600, 174665700, 
              3.32023599999963, 3.30058899999973, 3.48395499999974, 3.58873599999971, 
              3.41846799999982, 3.49705299999975, 3.54944299999964, 3.58218699999948, 
              3.6018339999997, 3.5887359999996), class = c("xts", "zoo"), index = structure(c(1546387200, 1546473600, 1546560000, 1546819200, 1546905600, 1546992000, 1547078400, 1547164800, 1547424000, 1547510400), tzone = "UTC", tclass = "Date"), .Dim = c(10L, 6L), .Dimnames = list(NULL, c("SPWR.Close", "SPWR.Volume", "SMA", "SMA.1", "obv", "VWAP"))) 

# convert to df
df1 <- as.data.frame(df)
# rownames (dates) to a new column
df1$DATE <- rownames(df1)

df1 %>% 
  # get data in a better format to print
  tidyr::pivot_longer(-DATE, names_to = "Variable", values_to = "Values") %>% 
  # fitler the variable you want to print
  dplyr::filter(Variable %in% c("SPWR.Close", "SMA", "SMA.1")) %>% 
  # plot using the group feature of ggplot2
  ggplot2::ggplot(aes(x = DATE, y = Values, group = Variable, color = Variable)) +
  ggplot2::geom_line()

您有一个 xts/zoo 系列,但问题中缺少相关的库调用。 zoo 有自己的经典绘图方法 (plot.zoo)、lattice (xyplot.zoo) 和 ggplot2 (autoplot.zoo).

我们使用 3 个面板使用 3 个面板,第二个面板用于交易量,第三个面板用于 OBV 以及在第一个面板中绘制的所有其他列,使用点表示收盘价、柱状图条表示交易量和所有其他列的线来说明下面的每一个。

1) plot.zoo 使用 plot.zoo(我们在最后显示 autoplot.zoo)参数屏幕、col 和类型有一个每列的元素通过 screen= 指定面板编号(或标签),通过 col= 指定颜色,并通过 type= 为该列指定类型(p = 点,l = 线,h = 直方图)。在图例中,我们在第一个参数中指定位置,在第二个参数中指定图例文本,通过 col= 指定颜色,通过 pch= 将列绘制为点(20 = 填充点)的点类型,将列绘制为线的线类型(1 =实线)通过 lty=,线宽通过 lwd=,点大小通过 pt.cex=,文本大小通过 cex=,剪裁(TRUE = 抑制剪裁)通过 xpd= 和边框(n = 周围没有边框图例)通过 bty=.

library(xts)

plot(transform(as.zoo(x), 
       SPWR.Volume = SPWR.Volume / 1000,
       obv  = obv / 1000000),
  main = "SPWR",
  ylab = c("Price", "Volume", "OBV"),
  screen = c(1, 2, 1, 1, 3, 1), 
  col = c("black", "blue", "green", "red", "black", "purple"),
  type = c("p", "h", "l", "l", "l", "l"),
  lwd = 2,
  heights = c(4, 1, 1)
)
legend("topleft", c("SMA", "SMA.1", "VWAP", "Close"), 
  col = c("green", "red", "purple", "black"), 
  pch = c(NA, NA, NA, 20), lty = c(1, 1, 1, NA),
  lwd = 2, pt.cex = 1.2, cex = 0.7, xpd = TRUE, bty = "n")

2) xyplot.zoo xyplot.zoo使用点阵图形。调用有点类似于plot.zoo.

library(lattice)
library(xts)

xyplot(transform(as.zoo(x),
                 SPWR.Volume = SPWR.Volume / 1000,
                 obv  = obv / 1000000),
  main = "SPWR",
  ylab = c("Price", "Volume", "OBV"),
  screen = c("Price", "Volume", "Price", "Price", "OBV", "Price"),
  col = c("black", "blue", "green", "red", "black", "purple"),
  type = list("p", "h", "l", "l", "l", "l"),
  lwd = 2,
  par.settings = list(layout.heights = list(panel = c(4, 1, 1)/6)),
  key = list(corner = c(0.05, 0.9),
    lines = list(col = c("green", "red", "purple")),
    text = list(c("SMA", "SMA.1", "VWAP"), cex = 0.7)
  )
)

3) autoplot.zoo ggplot2 相当复杂,但我们可以通过创建 3 个单独的图然后使用 cowplot 组合它们来实现。

library(cowplot)
library(ggplot2)
library(xts)

xx <- transform(as.zoo(x), 
  SPWR.Volume = SPWR.Volume / 1000,
  obv  = obv / 1000000)
p1 <- autoplot(xx$SPWR.Close, geom = "point") + 
  geom_line(aes(y = VWAP, col = "A"), x) +
  geom_line(aes(y = SMA, col = "B"), x) + 
  geom_line(aes(y = SMA.1, col = "C"), x) + 
  scale_color_manual(name = "Legend", 
    values = c(A = "purple", B = "green", C = "red"), 
    labels = c(A = "VWAP", B = "SMA", C = "SMA.1")) +
  theme(legend.position = c(0.1, 0.73), 
    plot.margin = margin(1, 1, -0.5, 1, "cm"),
    axis.text.x = element_blank(),
    axis.ticks.x = element_blank()) +
  ggtitle("SPWR") +
  xlab("") + 
  ylab("Price")
p2 <- autoplot(xx$SPWR.Volume, fill = "Volume", geom = "col") +
  scale_fill_manual(values = "blue") + 
  guides(fill = FALSE) +
  theme(plot.margin = margin(-0.5, 1, -0.5, 1, "cm")) +
  xlab("") + 
  ylab("Volume")
p3 <- autoplot(xx$obv) +
  theme(plot.margin = margin(-0.5, 1, 1, 1, "cm")) +
  ylab("OBV")
plot_grid(p1, p2, p3, align = "v", rel_heights = c(4, 1, 1), ncol = 1)