I just made my first interactive plotly graph in R. Now I would like to embed it in a blog post using iframes and have the data and the graph automatically update from an api at regular intervals. What is the best way to do that? Specifically, where can I host the plot? Is there a way to do it with shiny or RStudio Connect?
Update:
I have been trying to model my code based on the example provided by @ismirsehregal below. I can't figure out how to set xData and YData. I have the date on the x axis, so should the initial value of xData be set to the date variable? Should the initial value of y be set at NULL
as in the example? Etc. Here is what I have so far:
library(Quandl)
library(plotly)
library(shiny)
theme_set(theme_minimal())
ui <- fluidPage(
plotlyOutput("yield_chart")
)
server <- function(input, output, session) {
yield_chart <- plot_ly(DF, x = ~date, y = ~ten_yr, name = '10 Yr.', type = 'scatter', mode = 'lines', line=list(color='darkred')
)
output$linePlot <- renderPlotly({
yield_chart
})
lineProxy <- plotlyProxy("yield_chart", session)
xData <- reactiveVal(DF$date)
yData <- reactiveVal(NULL)
observe({
invalidateLater(1000)
treas_yields <- Quandl("USTREASURY/YIELD", api_key="123xyz")
DF <- treas_yields[, c("Date", "10 YR")]
colnames(DF) <- c("date", "ten_yr") # change var names
DF <- subset(DF, ten_yr!= 0)# drop rows with 0 values (e.g. April 14, 2017)
isolate(xData(xData()+1))
yData(DF$ten_yr)
})
observe({
plotlyProxyInvoke(lineProxy, "extendTraces", list(x = list(list(xData())), y = list(list(yData()))), list(0))
})
}
shinyApp(ui, server)
Here are the first 100 rows of data:
structure(list(date = structure(c(19006, 19005, 19004, 19003,
19002, 18999, 18998, 18997, 18996, 18995, 18992, 18991, 18990,
18989, 18988, 18984, 18983, 18982, 18981, 18978, 18977, 18976,
18975, 18974, 18971, 18970, 18969, 18968, 18967, 18964, 18963,
18962, 18961, 18960, 18957, 18955, 18954, 18953, 18950, 18949,
18948, 18947, 18946, 18943, 18941, 18940, 18939, 18936, 18935,
18934, 18933, 18932, 18929, 18928, 18927, 18926, 18925, 18922,
18921, 18920, 18919, 18918, 18915, 18914, 18913, 18912, 18908,
18907, 18906, 18905, 18904, 18901, 18900, 18899, 18898, 18897,
18894, 18893, 18892, 18891, 18890, 18887, 18886, 18885, 18884,
18883, 18880, 18879, 18878, 18877, 18873, 18872, 18871, 18870,
18869, 18866, 18865, 18864, 18863, 18862), class = "Date"), ten_yr = c(1.78,
1.7, 1.74, 1.75, 1.78, 1.76, 1.73, 1.71, 1.66, 1.63, 1.52, 1.52,
1.55, 1.49, 1.48, 1.5, 1.46, 1.48, 1.43, 1.41, 1.44, 1.47, 1.44,
1.42, 1.48, 1.49, 1.52, 1.48, 1.43, 1.35, 1.44, 1.43, 1.43, 1.52,
1.48, 1.64, 1.67, 1.63, 1.54, 1.59, 1.6, 1.63, 1.63, 1.58, 1.56,
1.46, 1.51, 1.45, 1.53, 1.6, 1.56, 1.58, 1.55, 1.57, 1.54, 1.63,
1.64, 1.66, 1.68, 1.65, 1.65, 1.59, 1.59, 1.52, 1.56, 1.59, 1.61,
1.58, 1.53, 1.54, 1.49, 1.48, 1.52, 1.55, 1.54, 1.48, 1.47, 1.41,
1.32, 1.33, 1.31, 1.37, 1.34, 1.31, 1.28, 1.33, 1.35, 1.3, 1.35,
1.38, 1.33, 1.29, 1.31, 1.3, 1.29, 1.31, 1.34, 1.35, 1.29, 1.25
)), row.names = c(NA, 100L), class = "data.frame")
The following shows how to use plotlyProxyInvoke
to call plotlys "extendTraces" JS function to add a datapoint to the plot each second:
library(shiny)
library(plotly)
ui <- fluidPage(
plotlyOutput("linePlot")
)
server <- function(input, output, session) {
initial_plot <- plot_ly(
x = 0,
y = 0,
type = 'scatter',
mode = 'lines'
)
output$linePlot <- renderPlotly({
initial_plot
})
lineProxy <- plotlyProxy("linePlot", session)
xData <- reactiveVal(0)
yData <- reactiveVal(NULL)
observe({
invalidateLater(1000)
isolate(xData(xData()+1))
yData(runif(n = 1, min = 0, max = 1))
})
observe({
plotlyProxyInvoke(lineProxy, "extendTraces", list(x = list(list(xData())), y = list(list(yData()))), list(0))
})
}
shinyApp(ui, server)
Also see my related answer here.
Edit: After the example data was explained.
Due to the fact, that your data source is updated only once every 24h I'd like to simplify things. The following solution re-renders the chart every minute (we have got the time for that) based on the latest data:
library(Quandl)
library(plotly)
library(shiny)
theme_set(theme_minimal())
ui <- fluidPage(
plotlyOutput("yield_chart"),
tags$style(type="text/css", "#yield_chart.recalculating { opacity: 1.0;"), # comment out to see the graph recalculating
)
server <- function(input, output, session) {
treas_yields <- reactive({
invalidateLater(1000*60) # update every minute
DF <- Quandl("USTREASURY/YIELD", api_key="123xyz")
subset(DF, `10 YR` != 0)
})
output$yield_chart <- renderPlotly({
print(paste(Sys.time(), "rendering plotly graph"))
plot_ly(treas_yields(), x = ~Date, y = ~`10 YR`, name = '10 Yr.', type = 'scatter', mode = 'lines', line=list(color='darkred'))
})
}
shinyApp(ui, server)