使用ggplotly rangelider进行互动的相对表现(股票收益)

时间:2019-06-11 21:28:21

标签: r dplyr r-plotly ggplotly rangeslider

我正在尝试从R中绘制交互式股票表现图。它是比较几种股票的相对表现。每只股票的表现线应从0%开始。

对于静态图,我将使用dplyr group_bymutate来计算性能(请参见我的代码)。

使用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 = "%"))

2 个答案:

答案 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