在ggplot2中绘制库存数据时遇到问题,x轴包含周末和假日的间隙。 this帖子非常有帮助,但在尝试使用有序因素时遇到了各种各样的问题。
library(xts)
library(grid)
library(dplyr)
library(scales)
library(bdscale)
library(ggplot2)
library(quantmod)
getSymbols("SPY", from = Sys.Date() - 1460, to = Sys.Date(), adjust = TRUE, auto.assign = TRUE)
input <- data.frame(SPY["2015/"])
names(input) <- c("Open", "High", "Low", "Close", "Volume", "Adjusted")
# i've tried changing rownames() to index(), and the plot looks good, but the x-axis is inaccurate
# i've also tried as.factor()
xaxis <- as.Date(rownames(input))
input$xaxis <- xaxis
p <- ggplot(input)
p <- p + geom_segment(aes(x = xaxis, xend = xaxis, y = Low, yend = High), size = 0.50) # body
p <- p + geom_segment(aes(x = xaxis - 0.4, xend = xaxis, y = Open, yend = Open), size = 0.90) # open
p <- p + geom_segment(aes(x = xaxis, xend = xaxis + 0.4, y = Close, yend = Close), size = 0.90) # close
p <- p + scale_y_continuous(scale_y_log10())
p + ggtitle("SPY: 2015")
上面的图表(没有红色框)是使用上面的代码段生成的。以下图表是尝试某些解决方案时的一些问题。首先,如果我尝试使用数据框的索引,我将生成一个漂亮的图形,但x轴是不准确的;该数据目前在10月份结束,但在下面的情节中,它将于7月结束:
xaxis <- as.Date(index(input))
其次,如果我尝试将rownames强制转换为有序因子,我会丢失水平刻度数据(表示打开和关闭)。
xaxis <- factor(rownames(input), ordered = TRUE)
如果我使用包bdscale,同样的问题是删除水平刻度,但网格线更清晰:
p <- p + scale_x_bd(business.dates = xaxis)
答案 0 :(得分:2)
您可能需要将日期视为离散值而不是连续值。这种方法略微简化了代码版本,可能如下所示:
getSymbols("SPY", from = Sys.Date() - 1460, to = Sys.Date(), adjust = TRUE, auto.assign = TRUE)
SPY <- SPY["2015/"]
colnames(SPY) <- sub("SPY.","", colnames(SPY))
month_brks <- c(1,endpoints(SPY, "months")[-1])
p <- ggplot(data.frame(xaxis=seq(nrow(SPY)), SPY))
p <- p + geom_linerange(aes(x=xaxis, ymin=Low, ymax=High), size=.5)
p <- p + geom_text(aes(x = xaxis, y = Open), size = 4., label="-", hjust=.7, vjust=0) # Open
p <- p + geom_text(aes(x = xaxis, y = Close), size = 4., label="-", hjust=-.1, vjust=0) # close
p <- p + scale_x_continuous(breaks=month_brks, labels=format(index(SPY)[month_brks], "%d %b %Y"))
p <- p + labs(title="SPY: 2015", x="Date", y="Price")
更新
更新了轴标签的处理。
答案 1 :(得分:2)
如果您想使用bdscale
,请告诉它使用更多网格线:
ggplot(input) +
geom_segment(aes(x = xaxis, xend = xaxis, y = Low, yend = High), size = 0.50) + # body
geom_segment(aes(x = xaxis - 0.4, xend = xaxis, y = Open, yend = Open), size = 0.90) + # open
geom_segment(aes(x = xaxis, xend = xaxis + 0.4, y = Close, yend = Close), size = 0.90) + # close
ggtitle("SPY: 2015") +
xlab('') + ylab('') +
scale_x_bd(business.dates=xaxis, max.major.breaks=10, labels=date_format("%b '%y")) # <==== !!!!
http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_SQLServer.html
它应该把十月放在那里的轴上,但它并不那么聪明。 Womp womp。拉请求欢迎!
答案 2 :(得分:1)
嗯,你可以手动调整它,但它有点hacky。首先,您应该使用索引,以便您的观察编号为1到188。
input$xaxis <-index(as.Date(rownames(input)))
然后你自己的情节代码:
p <- ggplot(input)
p <- p + geom_segment(aes(x = xaxis, xend = xaxis, y = Low, yend = High), size = 0.50) # body
p <- p + geom_segment(aes(x = xaxis - 0.4, xend = xaxis, y = Open, yend = Open), size = 0.90) # open
p <- p + geom_segment(aes(x = xaxis, xend = xaxis + 0.4, y = Close, yend = Close), size = 0.90) # close
p <- p + scale_y_continuous(scale_y_log10()) + ggtitle("SPY: 2015")
最后,我查看了应该在哪里进行休息的输入,并手动提供了标签:
p + scale_x_continuous(breaks=input$xaxis[c(1,62,125,188)], labels=c("jan","apr","jul","oct"))
请注意,我是懒惰的,只花了1-jan,1-apr 1-jul和1-oct的最近日期,因为1 jan是假日,标签“jan”低于2-jan。我把标签“oct”放在30-sep以下,这是input
中的最后一个条目。您可以根据需要对此进行调整。
当然,您可以自动化标签添加带有日期的标签字段并提取月份。
答案 3 :(得分:1)
下面的方法使用分面来删除缺失日期之间的空格,然后删除分面之间的空白区域以恢复未破坏的地块的外观。
首先,我们创建一个分组变量,每当日期中断时(代码改编自this SO answer),该变量会递增。我们稍后会将其用于分面。
input$group = c(0, cumsum(diff(input$xaxis) > 1))
现在我们将以下代码添加到您的图中。 facet_grid
在每个位置创建一个新方面,因为周末或假日,日期顺序中断。 scale_x_date
每周添加一次主要刻度线,每天添加次要网格线,但您可以调整此值。 theme
函数删除了构面条标签和构面之间的垂直空间:
p + facet_grid(. ~ group, space="free_x", scales="free_x") +
scale_x_date(breaks=seq(as.Date("2015-01-01"),max(input$xaxis), "1 week"),
minor_breaks="1 day",
labels=date_format("%b %d, %Y")) +
theme(axis.text.x=element_text(angle=-90, hjust=0.5, vjust=0.5, size=11),
panel.margin = unit(-0.05, "lines"),
strip.text=element_text(size=0),
strip.background=element_rect(fill=NA)) +
ggtitle("SPY: 2015")
这是结果图。周末和假期的空间消失了。每周都会有重大突破。我将scale_x_date
breaks
参数中的周数设置为星期四开始,因为星期四没有假期,因此每个方面都有一个主要的刻度标记。 (相比之下,默认休息时间会在星期一。由于假期通常在星期一,星期一假日的周数不会有默认休息时间的主要标记。)但是请注意,主要休息之间的间距本身就是根据当周市场开放的天数而有所不同。
答案 4 :(得分:1)
无法让OHLC工作 - 您认为自己需要自定义geom
。
我知道这不是你要求的,但我可以用美味的蜡烛图来诱惑你吗?
library(dplyr)
library(bdscale)
library(ggplot2)
library(quantmod)
library(magrittr)
library(scales)
getSymbols("SPY", from = Sys.Date() - 1460, to = Sys.Date(), adjust = TRUE, auto.assign = TRUE)
input <- data.frame(SPY["2015/"]) %>%
set_names(c("open", "high", "low", "close", "volume", "adjusted")) %>%
mutate(date=as.Date(rownames(.)))
input %>% ggplot(aes(x=date, ymin=low, ymax=high, lower=pmin(open,close), upper=pmax(open,close),
fill=open<close, group=date, middle=pmin(open,close))) +
geom_boxplot(stat='identity') +
ggtitle("SPY: 2015") +
xlab('') + ylab('') + theme(legend.position='none') +
scale_x_bd(business.dates=input$date, max.major.breaks=10, labels=date_format("%b '%y"))