用于OHLC图表的GGPlot使用条形图而不是蜡烛

时间:2015-01-28 20:17:24

标签: r charts ggplot2

我正在研究R中的ggplot,我正在尝试创建一个股票图表。我已经能够创建一个烛台图表,现在我想制作一个条形图。这包括从低价到高价的垂直线。然后,该行的左侧是开盘价的勾选,右侧是收盘价的勾选。我不知道如何添加此刻度。我能想到的最接近的是geom_errorbar,但这完全是另一回事,而胡须则是双向的。

此外,由于这是每日数据,ggplot为周末留出空间,这是不必要的。有没有办法删除这些空格?我在任何我一直在搜索的轴格式文章中都没有看到它。

谢谢。!

FOSL chart

使用低 - 高栏创建图表的可重现代码。

library(ggplot2)
library(quantmod)
FOSL <- getSymbols("FOSL", from="2015-01-01", auto.assign=FALSE)
names(FOSL) <- gsub("^.+\\.","",names(FOSL))  # remove "FOSL." from column names
FOSL <- data.frame(Date=as.Date(index(FOSL)), FOSL[,1:4])

ggplot(FOSL, aes(x=Date))+
  geom_linerange(aes(ymin=Low, ymax=High)) +
  labs(title="FOSL")

1 个答案:

答案 0 :(得分:2)

library(ggplot2)
library(quantmod)
FOSL <- getSymbols("FOSL", from="2015-01-01", auto.assign=FALSE)
names(FOSL) <- gsub("^.+\\.","",names(FOSL))  # remove "FOSL." from column names

rng <- "2015-08"
FOSL <- FOSL[rng]
FOSL <- data.frame(Date=as.POSIXct(index(FOSL)), FOSL[,1:4])

FOSL$chg <- ifelse(Cl(FOSL) > Op(FOSL), "up", "dn")
FOSL$width <- as.numeric(periodicity(FOSL)[1])

# Bar chart:

ggplot(data=FOSL, aes(x=Date, colour = chg)) +
  theme_bw() +
  geom_linerange(aes(ymin=Low, ymax=High)) +
  geom_segment(aes(y = Open, yend = Open, xend = Date - width / 2 )) +
  geom_segment(aes(y = Close, yend = Close, xend = Date + width / 2)) +
  scale_colour_manual(values = c("dn" = "darkred", "up" = "darkgreen")) + guides(colour = FALSE)

enter image description here

对于x轴标度如scale_x_datetime的ggplot图表,周末空间无法轻易删除。这是因为ggplot将POSIXct和日期数据解释为x-axis上来自原点的数字。例如as.numeric(as.POSIXct(“2015-09-25”))将是ggplot中x轴上的值。对于“hacks”,你可以查看这个SO答案,其中日期被视为因素:

R + ggplot2: how to hide missing dates from x-axis?

**编辑2016-05,从ggplot时间序列图中删除周末差距**

这是一个用于绘制ggplot OHLC条的工作示例,用于删除周末(此功能很容易修改以绘制蜡烛而不是条形example here)。

library(ggplot2)
library(quantmod)
library(lubridate)
# prepare data:
md <- getSymbols("FOSL", from="2015-01-01", auto.assign=FALSE)
names(md) <- gsub("^.+\\.","",names(md))  # remove "md." from column names
rng <- "2015-08"
md <- md[rng]
# Use ceiling date to ensure "Date" is rounded to 00:00:00 in POSIXct numeric scale from 1970, not Date scale.
md <- data.frame(Date = ceiling_date(as.POSIXct(index(md)), "day"), md[,1:4])
md$time_idx <- 1:NROW(md)



# Check special case of drawing of flat bars:
md[10, 2:5] <- md[10, 5]

gg_build_candlechart_without_weekends <- function(md,  # in data.frame format, with a Date column
                                               x_scale = 0.8,   # Controls thickness of bars
                                               width = 1
)
{
    stopifnot("Date" %in% colnames(md))
    md$chg <- ifelse(Cl(md) > Op(md), "up", "dn")
    md$time_idx <- 1:NROW(md)
    md$width <- width

    pl <- ggplot(md, aes(x = time_idx, colour = chg)) +
        geom_linerange(aes(ymin=Low, ymax=High)) +
        geom_segment(aes(y = Open, yend = Open, xend = time_idx - width / 2 * x_scale)) +
        geom_segment(aes(y = Close, yend = Close, xend = time_idx + width / 2 * x_scale)) +
        scale_colour_manual(values = c("dn" = "darkred", "up" = "darkgreen")) + guides(colour = FALSE) + labs(x = "Time", y = "Price")

    Nr <- NROW(md)
    maj_breaks <- round(Nr * c(0.05, 0.25, 0.5, 0.75, .95))

    periodicity <- quantile(diff(as.numeric(md$Date)), 0.5)
    if (periodicity < 86400) {
        label_timestamp <- "%b %d %H:%M:%S"
    } else {
        label_timestamp <- "%y' %b %d"
    }


    pl <- pl + scale_x_continuous(limits = c(0, Nr + 1), expand = c(0, 0), breaks = maj_breaks, labels = format(md$Date[maj_breaks], label_timestamp), minor_breaks = Nr * seq(0.1, 0.9, by = 0.2))

    # draw flat bars as special case:
    md_flatbars <- md[md$High == md$Low, ]
    if (NROW(md_flatbars) > 0) {
        pl <- pl + geom_segment(data = md_flatbars, aes(x = time_idx - width / 2 * x_scale, y = Close, yend = Close, xend = time_idx + width / 2 * x_scale))
    }

    pl
}

gg_build_candlechart_without_weekends(md, x_scale = 0.8, width = 1)

No weekend gaps