闪亮的应用程序:在 renderPlot 之外下载数据源以加快用户操作
Shiny app: Download data source outside of renderPlot for quicker user manipulation
这是我的第一个闪亮的应用程序。我希望用户能够更新构面列的数量和下载图的尺寸。 readNWISuv
,如果查询多年,下载数据的功能会耗时较长。目前,每次用户想要更改绘图格式或绘图尺寸时,该应用程序都会下载数据。不确定我是否需要使用 reactiveValues
,但我假设我希望在 renderPlot
之外下载和操作数据。谢谢!
library(shiny)
library(dataRetrieval)
library(lubridate)
library(tidyverse)
library(plotly)
#flow wrecker
ui <- pageWithSidebar( #fluidPage(
# Application title
titlePanel("Flow Record"),
# Sidebar with a date input
#sidebarLayout
sidebarPanel(
dateRangeInput("daterange", "Date range: (yyyy-mm-dd)",
start = Sys.Date()-10,
min = "1980-10-01"),
textInput("gage", "USGS Gage #", "11532500"),
#actionButton("dload","Download data"),
selectInput("facet_x", "Facet Column #:", 2, choices =1:4),
submitButton("Update View", icon("refresh")),
helpText("When you click the button above, you should see",
"the output below update to reflect the values you",
"entered above:"),
#verbatimTextOutput("value"),
downloadButton('downloadImage', 'Download figure'),
numericInput("fig_x", "Fig. Dim. x:", 10, min = 3, max = 16),
numericInput("fig_y", "Fig. Dim. y:", 10, min = 3, max = 16),
width = 3
),
# Show a plot of the generated WY
mainPanel(
plotlyOutput("WYfacet")
)
)
# Define server draw WY facets
server <- function(input, output) {
parameterCd <- "00060" # discharge
#water year
wtr_yr <- function(dates, start_month=10) {
# Convert dates into POSIXlt
dates.posix = as.POSIXlt(dates)
# Year offset
offset = ifelse(dates.posix$mon >= start_month - 1, 1, 0)
# Water year
adj.year = dates.posix$year + 1900 + offset
# Return the water year
adj.year
}
output$WYfacet <- renderPlotly({
#progress bar
withProgress(readNWISuv(input$gage, parameterCd, input$daterange[1], input$daterange[2],tz="America/Los_Angeles") %>% addWaterYear,
message = 'Download in progress',
detail = 'This may take a while...', value = 1)
#download
temperatureAndFlow <- readNWISuv(input$gage, parameterCd, input$daterange[1], input$daterange[2],tz="America/Los_Angeles") %>% addWaterYear
names(temperatureAndFlow)<-c("agc","site","date","WY", "flow","a","tzone")
temperatureAndFlow$commonDate <- as.Date(format(temperatureAndFlow$date, format="2000-%m-%d"))
tf.df<-temperatureAndFlow %>%
filter(WY<=max(WY) & WY>=if_else(month(min(date))<10,min(WY)+1,min(WY)))
tf.df$date.d<-format(tf.df$date, format="%Y-%m-%d")
#mutate commonDate
df4 <- tf.df %>%
mutate(WY=factor(wtr_yr(date.d))) %>%
#seq along dates starting with the beginning of your water year
mutate(commonDate=as.Date(paste0(ifelse(month(date.d) < 10, "2001", "2000"),
"-", month(date.d), "-", day(date.d))), Date=date.d)
#plot
ploty<-ggplot(data = df4,mapping = aes(x = commonDate, y = flow,label=Date, colour = factor(WY))) +
geom_line() +
labs(x = " ", y = "Discharge (cfs)") +
facet_wrap(facets = ~WY,ncol=as.integer(input$facet_x)) +
scale_y_log_eng()+
annotation_logticks(sides = "l")+
theme_bw()+
theme(panel.grid.minor.x = element_blank())+
scale_x_date(labels = function(x) format(x, "%b"),date_breaks = "1 months")+
guides(colour=FALSE)
ggplotly(ploty, tooltip=c("flow","Date"))
})
#fig dimensions
output$fig_x <- renderText({ input$fig_x })
output$fig_y <- renderText({ input$fig_y })
#facet columns
output$facet_x <- renderText({ input$facet_x })
#download to computer
output$downloadImage <- downloadHandler(
filename = function(){paste("plot",'.png',sep='')},
content = function(file){
ggsave(file,width = input$fig_x,height = input$fig_y, dpi = 600, units = "in", device='png')
print(ggplot(data = df4,mapping = aes(x = commonDate, y = flow, colour = factor(WY))) +
geom_line() +
#geom_point()+
#geom_vline(data = trip,aes(xintercept=commonDate),trip_df,color="black")+
labs(x = " ", y = "Discharge (cfs)") +
facet_wrap(facets = ~WY,ncol=as.integer(input$facet_x)) +
scale_y_log_eng()+
annotation_logticks(sides = "l")+
theme_bw()+
theme(panel.grid.minor.x = element_blank())+
scale_x_date(labels = function(x) format(x, "%b"),date_breaks = "1 months")+
guides(colour=FALSE))
})
}
# Run the application
shinyApp(ui = ui, server = server)
要使这项工作正常进行,需要对您的服务器部分进行一些更改。主要是:
- 将数据帧的创建拆分为一个新的
eventReactive
函数,依赖于 actionButton
。
- 引用
renderPlotly
调用中的函数
试试这个:
## Within ui function call ############################################
# submitButton("Update View", icon("refresh")), # line to replace
actionButton(inputId = "update", "Update View", icon("refresh")),
## (if you want to keep a button to control when data is downloaded ##
server <- function(input, output) {
parameterCd <- "00060" # discharge
#water year
wtr_yr <- function(dates, start_month=10) {
# Convert dates into POSIXlt
dates.posix = as.POSIXlt(dates)
# Year offset
offset = ifelse(dates.posix$mon >= start_month - 1, 1, 0)
# Water year
adj.year = dates.posix$year + 1900 + offset
# Return the water year
adj.year
}
# New part here - use `reactive` to make df4 a new thing, which is processed separately. The `eventReactive` function waits till it sees the button pressed.
df4 <- eventReactive(input$update, ignoreNULL = FALSE, {
#progress bar
withProgress(readNWISuv(input$gage, parameterCd, input$daterange[1], input$daterange[2],tz="America/Los_Angeles") %>% addWaterYear,
message = 'Download in progress',
detail = 'This may take a while...', value = 1)
#download
temperatureAndFlow <- readNWISuv(input$gage, parameterCd, input$daterange[1], input$daterange[2],tz="America/Los_Angeles") %>% addWaterYear
names(temperatureAndFlow)<-c("agc","site","date","WY", "flow","a","tzone")
temperatureAndFlow$commonDate <- as.Date(format(temperatureAndFlow$date, format="2000-%m-%d"))
tf.df<-temperatureAndFlow %>%
filter(WY<=max(WY) & WY>=if_else(month(min(date))<10,min(WY)+1,min(WY)))
tf.df$date.d<-format(tf.df$date, format="%Y-%m-%d")
#mutate commonDate
tf.df %>%
mutate(WY=factor(wtr_yr(date.d))) %>%
#seq along dates starting with the beginning of your water year
mutate(commonDate=as.Date(paste0(ifelse(month(date.d) < 10, "2001", "2000"),
"-", month(date.d), "-", day(date.d))), Date=date.d)
})
output$WYfacet <- renderPlotly({
# req will pause plot loading till new data downloaded above, but changes to display will render without new download
req(df4())
#plot
ploty<-ggplot(data = df4(), # Put brackets here to refer to df4 as a reactive input!!!
mapping = aes(x = commonDate, y = flow, label=Date, colour = factor(WY))) +
geom_line() +
labs(x = " ", y = "Discharge (cfs)") +
facet_wrap(facets = ~WY,ncol=as.integer(input$facet_x)) +
scale_y_log10()+
# annotation_logticks(sides = "l")+
theme_bw()+
theme(panel.grid.minor.x = element_blank())+
scale_x_date(labels = function(x) format(x, "%b"),date_breaks = "1 months")+
guides(colour=FALSE)
ggplotly(ploty, tooltip=c("flow","Date"))
})
#fig dimensions
output$fig_x <- renderText({ input$fig_x })
output$fig_y <- renderText({ input$fig_y })
#facet columns
output$facet_x <- renderText({ input$facet_x })
#download to computer
output$downloadImage <- downloadHandler(
filename = function(){paste("plot",'.png',sep='')},
content = function(file){
ggsave(file,width = input$fig_x,height = input$fig_y, dpi = 600, units = "in", device='png')
print(ggplot(data = df4() ,mapping = aes(x = commonDate, y = flow, colour = factor(WY))) +
geom_line() +
#geom_point()+
#geom_vline(data = trip,aes(xintercept=commonDate),trip_df,color="black")+
labs(x = " ", y = "Discharge (cfs)") +
facet_wrap(facets = ~WY,ncol=as.integer(input$facet_x)) +
scale_y_log10()+
annotation_logticks(sides = "l")+
theme_bw()+
theme(panel.grid.minor.x = element_blank())+
scale_x_date(labels = function(x) format(x, "%b"),date_breaks = "1 months")+
guides(colour=FALSE))
})
}
这是我的第一个闪亮的应用程序。我希望用户能够更新构面列的数量和下载图的尺寸。 readNWISuv
,如果查询多年,下载数据的功能会耗时较长。目前,每次用户想要更改绘图格式或绘图尺寸时,该应用程序都会下载数据。不确定我是否需要使用 reactiveValues
,但我假设我希望在 renderPlot
之外下载和操作数据。谢谢!
library(shiny)
library(dataRetrieval)
library(lubridate)
library(tidyverse)
library(plotly)
#flow wrecker
ui <- pageWithSidebar( #fluidPage(
# Application title
titlePanel("Flow Record"),
# Sidebar with a date input
#sidebarLayout
sidebarPanel(
dateRangeInput("daterange", "Date range: (yyyy-mm-dd)",
start = Sys.Date()-10,
min = "1980-10-01"),
textInput("gage", "USGS Gage #", "11532500"),
#actionButton("dload","Download data"),
selectInput("facet_x", "Facet Column #:", 2, choices =1:4),
submitButton("Update View", icon("refresh")),
helpText("When you click the button above, you should see",
"the output below update to reflect the values you",
"entered above:"),
#verbatimTextOutput("value"),
downloadButton('downloadImage', 'Download figure'),
numericInput("fig_x", "Fig. Dim. x:", 10, min = 3, max = 16),
numericInput("fig_y", "Fig. Dim. y:", 10, min = 3, max = 16),
width = 3
),
# Show a plot of the generated WY
mainPanel(
plotlyOutput("WYfacet")
)
)
# Define server draw WY facets
server <- function(input, output) {
parameterCd <- "00060" # discharge
#water year
wtr_yr <- function(dates, start_month=10) {
# Convert dates into POSIXlt
dates.posix = as.POSIXlt(dates)
# Year offset
offset = ifelse(dates.posix$mon >= start_month - 1, 1, 0)
# Water year
adj.year = dates.posix$year + 1900 + offset
# Return the water year
adj.year
}
output$WYfacet <- renderPlotly({
#progress bar
withProgress(readNWISuv(input$gage, parameterCd, input$daterange[1], input$daterange[2],tz="America/Los_Angeles") %>% addWaterYear,
message = 'Download in progress',
detail = 'This may take a while...', value = 1)
#download
temperatureAndFlow <- readNWISuv(input$gage, parameterCd, input$daterange[1], input$daterange[2],tz="America/Los_Angeles") %>% addWaterYear
names(temperatureAndFlow)<-c("agc","site","date","WY", "flow","a","tzone")
temperatureAndFlow$commonDate <- as.Date(format(temperatureAndFlow$date, format="2000-%m-%d"))
tf.df<-temperatureAndFlow %>%
filter(WY<=max(WY) & WY>=if_else(month(min(date))<10,min(WY)+1,min(WY)))
tf.df$date.d<-format(tf.df$date, format="%Y-%m-%d")
#mutate commonDate
df4 <- tf.df %>%
mutate(WY=factor(wtr_yr(date.d))) %>%
#seq along dates starting with the beginning of your water year
mutate(commonDate=as.Date(paste0(ifelse(month(date.d) < 10, "2001", "2000"),
"-", month(date.d), "-", day(date.d))), Date=date.d)
#plot
ploty<-ggplot(data = df4,mapping = aes(x = commonDate, y = flow,label=Date, colour = factor(WY))) +
geom_line() +
labs(x = " ", y = "Discharge (cfs)") +
facet_wrap(facets = ~WY,ncol=as.integer(input$facet_x)) +
scale_y_log_eng()+
annotation_logticks(sides = "l")+
theme_bw()+
theme(panel.grid.minor.x = element_blank())+
scale_x_date(labels = function(x) format(x, "%b"),date_breaks = "1 months")+
guides(colour=FALSE)
ggplotly(ploty, tooltip=c("flow","Date"))
})
#fig dimensions
output$fig_x <- renderText({ input$fig_x })
output$fig_y <- renderText({ input$fig_y })
#facet columns
output$facet_x <- renderText({ input$facet_x })
#download to computer
output$downloadImage <- downloadHandler(
filename = function(){paste("plot",'.png',sep='')},
content = function(file){
ggsave(file,width = input$fig_x,height = input$fig_y, dpi = 600, units = "in", device='png')
print(ggplot(data = df4,mapping = aes(x = commonDate, y = flow, colour = factor(WY))) +
geom_line() +
#geom_point()+
#geom_vline(data = trip,aes(xintercept=commonDate),trip_df,color="black")+
labs(x = " ", y = "Discharge (cfs)") +
facet_wrap(facets = ~WY,ncol=as.integer(input$facet_x)) +
scale_y_log_eng()+
annotation_logticks(sides = "l")+
theme_bw()+
theme(panel.grid.minor.x = element_blank())+
scale_x_date(labels = function(x) format(x, "%b"),date_breaks = "1 months")+
guides(colour=FALSE))
})
}
# Run the application
shinyApp(ui = ui, server = server)
要使这项工作正常进行,需要对您的服务器部分进行一些更改。主要是:
- 将数据帧的创建拆分为一个新的
eventReactive
函数,依赖于actionButton
。 - 引用
renderPlotly
调用中的函数
试试这个:
## Within ui function call ############################################
# submitButton("Update View", icon("refresh")), # line to replace
actionButton(inputId = "update", "Update View", icon("refresh")),
## (if you want to keep a button to control when data is downloaded ##
server <- function(input, output) {
parameterCd <- "00060" # discharge
#water year
wtr_yr <- function(dates, start_month=10) {
# Convert dates into POSIXlt
dates.posix = as.POSIXlt(dates)
# Year offset
offset = ifelse(dates.posix$mon >= start_month - 1, 1, 0)
# Water year
adj.year = dates.posix$year + 1900 + offset
# Return the water year
adj.year
}
# New part here - use `reactive` to make df4 a new thing, which is processed separately. The `eventReactive` function waits till it sees the button pressed.
df4 <- eventReactive(input$update, ignoreNULL = FALSE, {
#progress bar
withProgress(readNWISuv(input$gage, parameterCd, input$daterange[1], input$daterange[2],tz="America/Los_Angeles") %>% addWaterYear,
message = 'Download in progress',
detail = 'This may take a while...', value = 1)
#download
temperatureAndFlow <- readNWISuv(input$gage, parameterCd, input$daterange[1], input$daterange[2],tz="America/Los_Angeles") %>% addWaterYear
names(temperatureAndFlow)<-c("agc","site","date","WY", "flow","a","tzone")
temperatureAndFlow$commonDate <- as.Date(format(temperatureAndFlow$date, format="2000-%m-%d"))
tf.df<-temperatureAndFlow %>%
filter(WY<=max(WY) & WY>=if_else(month(min(date))<10,min(WY)+1,min(WY)))
tf.df$date.d<-format(tf.df$date, format="%Y-%m-%d")
#mutate commonDate
tf.df %>%
mutate(WY=factor(wtr_yr(date.d))) %>%
#seq along dates starting with the beginning of your water year
mutate(commonDate=as.Date(paste0(ifelse(month(date.d) < 10, "2001", "2000"),
"-", month(date.d), "-", day(date.d))), Date=date.d)
})
output$WYfacet <- renderPlotly({
# req will pause plot loading till new data downloaded above, but changes to display will render without new download
req(df4())
#plot
ploty<-ggplot(data = df4(), # Put brackets here to refer to df4 as a reactive input!!!
mapping = aes(x = commonDate, y = flow, label=Date, colour = factor(WY))) +
geom_line() +
labs(x = " ", y = "Discharge (cfs)") +
facet_wrap(facets = ~WY,ncol=as.integer(input$facet_x)) +
scale_y_log10()+
# annotation_logticks(sides = "l")+
theme_bw()+
theme(panel.grid.minor.x = element_blank())+
scale_x_date(labels = function(x) format(x, "%b"),date_breaks = "1 months")+
guides(colour=FALSE)
ggplotly(ploty, tooltip=c("flow","Date"))
})
#fig dimensions
output$fig_x <- renderText({ input$fig_x })
output$fig_y <- renderText({ input$fig_y })
#facet columns
output$facet_x <- renderText({ input$facet_x })
#download to computer
output$downloadImage <- downloadHandler(
filename = function(){paste("plot",'.png',sep='')},
content = function(file){
ggsave(file,width = input$fig_x,height = input$fig_y, dpi = 600, units = "in", device='png')
print(ggplot(data = df4() ,mapping = aes(x = commonDate, y = flow, colour = factor(WY))) +
geom_line() +
#geom_point()+
#geom_vline(data = trip,aes(xintercept=commonDate),trip_df,color="black")+
labs(x = " ", y = "Discharge (cfs)") +
facet_wrap(facets = ~WY,ncol=as.integer(input$facet_x)) +
scale_y_log10()+
annotation_logticks(sides = "l")+
theme_bw()+
theme(panel.grid.minor.x = element_blank())+
scale_x_date(labels = function(x) format(x, "%b"),date_breaks = "1 months")+
guides(colour=FALSE))
})
}