Shiny R renderPlots on the fly
If anyone's still interested in an answer, try this:
library(shiny)
runApp(shinyApp(
ui = shinyUI(
fluidPage(
numericInput("number", label = NULL, value = 1, step = 1, min = 1),
uiOutput("plots")
)
),
server = function(input, output) {
### This is the function to break the whole data into different blocks for each page
plotInput <- reactive({
n_plot <- input$number
total_data <- lapply(1:n_plot, function(i){rnorm(500)})
return (list("n_plot"=n_plot, "total_data"=total_data))
})
##### Create divs######
output$plots <- renderUI({
plot_output_list <- lapply(1:plotInput()$n_plot, function(i) {
plotname <- paste("plot", i, sep="")
plotOutput(plotname, height = 280, width = 250)
})
do.call(tagList, plot_output_list)
})
observe({
lapply(1:plotInput()$n_plot, function(i){
output[[paste("plot", i, sep="") ]] <- renderPlot({
hist(plotInput()$total_data[[i]], main = paste("Histogram Nr", i))
})
})
})
}
))
R/shiny: render elements of plots only when needed in shiny apps
So maybe try grDevices
, like here:
server.R:
library("shiny")
library("grDevices")
data(iris)
plot(x=NA, y=NA, xlim=c(0,10), ylim=c(0,10))
p <- recordPlot()
function(input, output, session) {
output$plotPoints <- renderPlot({
replayPlot(p)
points(1:input$ile)
})
}
and ui.R:
library(shiny)
fluidPage(
sidebarPanel(
sliderInput("ile", min=1, max=10, label="", value=5)
),
mainPanel(
plotOutput("plotPoints"))
)
Plot the Plotly Graph Dynamically in the Shiny App in R
This was more complicated than it looked. It looks like you want to iterate and create a series of plotly graphs, changing the data values as you go along.
Because the Generations
slider re-initializes the vector to a new length,
and each iteration changes the state of the data being plotted, you can't just cascade reactive functions. Storing the state in a reactiveValues
is a good way to handle this.
The major changes were as follows:
- Added a
reactiveValues
to storexAxis
andyAxis
- Added an
observeEvent
to reinitialize those values when its value change - Added an "Iteration range" slider to drive the iteration (easier than a reactive timer). Note that it has an
animate
parameter that (probably) creates a reactive timer on its own. - Modified the plotly call to make it more conventional and avoid warnings.
The code:
library(shiny)
library(plotly)
u <- fluidPage(
titlePanel("Iterations of a plotly graph"),
sidebarLayout(
sidebarPanel(
sliderInput("Generations","Number of Generations:",
min = 1, max = 50, value = 20),
sliderInput("iter", "Iteration range:",
value = 1, min = 1, max = 1000, step = 1,
animate=animationOptions(interval=800, loop=T)),
p("To start click on the blue arrowhead")
),
mainPanel(
plotlyOutput("GA")
)
))
s <- shinyServer(function(input,output){
rv <- reactiveValues(xAxis=NULL,yAxis=NULL)
observeEvent(input$Generations,{
rv$xAxis=vector("numeric", as.numeric(input$Generations))
rv$yAxis=vector("numeric", as.numeric(input$Generations))
})
output$GA = renderPlotly({
rv$yAxis[input$iter] <- input$iter
rv$xAxis[input$iter] <- input$iter
gdf <- data.frame(xAxis=rv$xAxis, yAxis=rv$yAxis)
plot_ly(gdf, x = ~xAxis, y = ~yAxis, type="scatter",mode="markers")
})
})
shinyApp(u,s)
Because it is dynamic, you have to run it to see how it really works, but here is a screen shot after several iterations:
Clicking through plots in Shiny app
You just need to use the variable that will maintain the count for each click:
library(shiny)
server <- function(input, output, session) {
# data
v <- c(9,8,7,8,9,5,6,7,4,3)
w <- c(3,4,2,3,3,3,2,3,4,5)
x <- c(1,3,4,6,2,4,6,8,6,3)
y <- c(4,5,2,4,2,1,2,5,7,8)
z <- c(5,9,8,6,4,6,8,9,6,7)
df <- data.frame(v, w, x, y, z)
# initial plot that will allow user to change parameters (haven't implemented yet)
output$plot <- renderPlot(plot(df[[1]],df[[2]]))
count<-0 # This is the counter which keeps track on button count
observeEvent(input$run, {
count <<- count + 1 # Increment the counter by 1 when button is click
if(count<6){
# Draw the plot if count is less than 6
output$plot <- renderPlot(plot(df[[1]],df[[count]],main = count))
}
else{
# Reset the counter if it is more than 5
count <- 0
}
})
}
ui <- fluidPage(
actionButton("run", "Generate"),
plotOutput("plot")
)
shinyApp(ui = ui, server = server)
dynamically add plots to web page using shiny
Perhaps this example due to Winston Chang is helpful:
Shiny example app with dynamic number of plots
Here is the full example just in case of linkrot:
server.R
max_plots <- 5
shinyServer(function(input, output) {
# Insert the right number of plot output objects into the web page
output$plots <- renderUI({
plot_output_list <- lapply(1:input$n, function(i) {
plotname <- paste("plot", i, sep="")
plotOutput(plotname, height = 280, width = 250)
})
# Convert the list to a tagList - this is necessary for the list of items
# to display properly.
do.call(tagList, plot_output_list)
})
# Call renderPlot for each one. Plots are only actually generated when they
# are visible on the web page.
for (i in 1:max_plots) {
# Need local so that each item gets its own number. Without it, the value
# of i in the renderPlot() will be the same across all instances, because
# of when the expression is evaluated.
local({
my_i <- i
plotname <- paste("plot", my_i, sep="")
output[[plotname]] <- renderPlot({
plot(1:my_i, 1:my_i, xlim = c(1, max_plots), ylim = c(1, max_plots), main = paste("1:", my_i, ". n is ", input$n, sep = ""))
})
})
}
})
ui.R
shinyUI(pageWithSidebar(
headerPanel("Dynamic number of plots"),
sidebarPanel(
sliderInput("n", "Number of plots", value=1, min=1, max=5)
),
mainPanel(
uiOutput("plots") # This is the dynamic UI for the plots
)
))
Update dynamically created plot in R Shiny
I can dynamically generate any compound ui, as I can create named inputs and outputs dynamically and then they respond to events as usual.
#ui.R
library(shiny)
# Define UI for application that plots random distributions
shinyUI(pageWithSidebar(
headerPanel("Example"),
# Sidebar with a slider input for number of observations
sidebarPanel(
checkboxInput("show_dynamic_ui", label="Show dynamic UI", value=TRUE)
),
# Show a plot of the generated distribution
mainPanel(
uiOutput("dynamic_ui")
)
))
#server.R
library(shiny)
shinyServer(function(input, output, session) {
output$dynamic_ui <- renderUI({
if (input$show_dynamic_ui) #NULL when not checked
fluidPage(
fluidRow(column(6, sliderInput("dinput", "Number of observations:",min=1, max=1000, value=500))),
fluidRow(column(12, plotOutput("dplot")))
)
})
output$dplot<-renderPlot({
dist <- rnorm(as.integer(input$dinput))
hist(dist)
})
})
Plot by variable in Shiny
I am not sure this is what you are looking for, but hope this will help.
Instead of multiple if
statements, you can just make sure the input$var
selected is one of the 3 variables of interest (sex, intubated, or support). isolate
is included so the plot is not automatically redrawn, until input$go
is selected as you currently have it.
You can use aes_string
and pass in input$var
which has the character value of the column you wish to plot. If you want the line plots with counts, you can use geom_line(stat = 'count')
.
server <- function(input, output) {
dataInput <- reactive({
subset(data_n, date >= input$range[1] & date <= input$range[2])
})
plotInput <- eventReactive(input$go, {
if (c(isolate(input$var)) %in% c("sex", "intubated", "support")) {
ggplot(data = dataInput(), aes_string(x = "date", group = input$var, color = input$var)) +
geom_line(stat = 'count')
}
})
output$plot_neo <- renderPlot({
plotInput()
})
}
Related Topics
Ggplot2 - Shade Area Between Two Vertical Lines
Change the Color and Font of Text in Shiny App
What Is the Correct Way to Ask for User Input in an R Program
Change Color of Only One Bar in Ggplot
Center-Align Legend Title and Legend Keys in Ggplot2 for Long Legend Titles
How to Define a Vectorized Function in R
Geom_Point() and Geom_Line() for Multiple Datasets on Same Graph in Ggplot2
Replace Na with 0 in a Data Frame Column
How to Adjust Facet Size Manually
Fast Replacing Values in Dataframe in R
Determining the Distance Between Two Zip Codes (Alternatives to Mapdist)
How to Host a Shiny App on a Windows MAChine
Optimal/Efficient Plotting of Survival/Regression Analysis Results
How to Group by All But One Columns
How to Use Grid to Edit a Ggplot2 Object to Add Math Expressions to Facet Labels