我正在尝试从R中绘制交互式股票表现图。它是比较几种股票的相对表现。每只股票的表现线应从0%开始。
对于静态图,我将使用dplyr group_by
和mutate
来计算性能(请参见我的代码)。
使用ggplot2和plotly / ggplotly,rangeslider()
可以交互地选择x轴范围。现在,我希望性能从所选的任何起始范围开始为0。
我如何将dplyr计算移到绘图中,或者有一个反馈环可以在范围更改时重新计算?
理想情况下,它应该在静态RMarkdown HTML中可用。或者,我也将切换为“闪亮”。
我尝试了几个options for rangeslider。我也尝试了ggplot stat_function
,但是无法达到预期的结果。另外,我发现dygraphs具有dyRangeSelector
。但我在这里也面临着同样的问题。
这是我的代码:
library(plotly)
library(tidyquant)
stocks <- tq_get(c("AAPL", "MSFT"), from = "2019-01-01")
range_from <- as.Date("2019-02-01")
stocks_range <- stocks %>%
filter(date >= range_from) %>%
group_by(symbol) %>%
mutate(performance = adjusted/first(adjusted)-1)
p <- stocks_range %>%
ggplot(aes(x = date, y = performance, color = symbol)) +
geom_line()
ggplotly(p, dynamicTicks = T) %>%
rangeslider(borderwidth = 1) %>%
layout(hovermode = "x", yaxis = list(tickformat = "%"))
答案 0 :(得分:2)
如果您不想使用shiny
,则可以在dyRebase
中使用dygraphs
选项,也可以在{{1 }}。在这两个示例中,我都将基数减为1,而不是零。
选项1:带有javascript
plotly
请注意,dyRebase(value = 0)不起作用。
选项2:dygraphs
使用event handlers。我尝试避免使用library(dygraphs)
library(tidyquant)
library(timetk)
library(tidyr)
stocks <- tq_get(c("AAPL", "MSFT"), from = "2019-01-01")
stocks %>%
dplyr::select(symbol, date, adjusted) %>%
tidyr::spread(key = symbol, value = adjusted) %>%
timetk::tk_xts() %>%
dygraph() %>%
dyRebase(value = 1) %>%
dyRangeSelector()
,因此避免使用plotly
解决方案。这里的时间选择只是通过缩放,但是我认为也可以通过范围选择器来完成。 ggplotly
中的plot_ly
代码将每个跟踪重新定位到第一个可见数据点(注意可能的缺失值)。只能通过javascript
事件来调用它,因此必须在绘图之前完成第一次变基。
onRenderRebaseTxt
答案 1 :(得分:0)
我找到了plotly_relayout
的解决方案,该解决方案读取了可见的x轴范围。这用于重新计算性能。它可以作为闪亮的应用程序。这是我的代码:
library(shiny)
library(plotly)
library(tidyquant)
library(lubridate)
stocks <- tq_get(c("AAPL", "MSFT"), from = "2019-01-01")
ui <- fluidPage(
titlePanel("Rangesliding performance"),
mainPanel(
plotlyOutput("plot")
)
)
server <- function(input, output) {
d <- reactive({ e <- event_data("plotly_relayout")
if (is.null(e)) {
e$xaxis.range <- c(min(stocks$date), max(stocks$date))
}
e })
stocks_range_dyn <- reactive({
s <- stocks %>%
group_by(symbol) %>%
mutate(performance = adjusted/first(adjusted)-1)
if (!is.null(d())) {
s <- s %>%
mutate(performance = adjusted/nth(adjusted, which.min(abs(date - date(d()$xaxis.range[[1]]))))-1)
}
s
})
output$plot <- renderPlotly({
plot_ly(stocks_range_dyn(), x = ~date, y = ~performance, color = ~symbol) %>%
add_lines() %>%
rangeslider(start = d()$xaxis.range[[1]], end = d()$xaxis.range[[2]], borderwidth = 1)
})
}
shinyApp(ui = ui, server = server)
定义rangeslider的开始/结束仅适用于plot_ly
,不适用于ggplotly
转换的ggplot对象。我不确定这是否是错误,因此打开了issue on Github。