Reputation: 320
I want to dinamically generate plots using shiny, but each plot with a different title.
I have tried using the for bucle to generate n number of plots and show them using an observeEvent, but this is not working for me, as the main of the plot is ignored.
To ensure that each plot has its own main title, what I do is to store the title into a data.frame and access to it from the plot.
Here the code:
library(shiny)
ui <- fluidPage(
textInput("title","Title",""),
actionButton("generate","Plot"),
div(class="aux",style="width:300px;height:200px")
)
server <- function(input,output){
observeEvent(input$generate,{
insertUI(
selector= ".aux",
where="beforeBegin",
ui = plotOutput(paste0("plot",input$generate))
)
if(input$generate == 1){
data <<- data.frame(title = input$title)
}else{
aux <- data.frame(title=input$title)
data <<- rbind(data,aux)
}
})
for(i in 1:10){
output[[paste0("plot",i)]] <- renderPlot(
plot(rnorm(100),main=data[i,"title"])
)
}
}
shinyApp(ui,server)
This other code do what I really want to do, but it is not good programing to declare manually the plots:
library(shiny)
ui <- fluidPage(
textInput("title","Title",""),
actionButton("generate","Plot"),
div(class="aux",style="width:300px;height:200px")
)
server <- function(input,output){
observeEvent(input$generate,{
insertUI(
selector= ".aux",
where="beforeBegin",
ui = plotOutput(paste0("plot",input$generate))
)
if(input$generate == 1){
data <<- data.frame(title = input$title)
}else{
aux <- data.frame(title=input$title)
data <<- rbind(data,aux)
}
})
output$plot1 <- renderPlot(
plot(rnorm(100),main=data[1,"title"])
)
output$plot2 <- output$plot1 <- renderPlot(
plot(rnorm(100),main=data[2,"title"])
)
}
shinyApp(ui,server)
EDITED:
Using the recomendations of Stephane Laurent, I have put the insertUI and output[[plot]] inside the observeEvent, but this not solves the issue to be able to edit the plot title changing the data.frame title. Here the code:
library(shiny)
library(data.table)
ui <- fluidPage(
column(6,
textInput("title","Title",""),
actionButton("generate","Plot"),
div(id="aux")),
column(6,
textInput("newt","New title",""),
selectInput("row","Row",choices=c(1:10)),
actionButton("change","Change title"))
)
server <- function(input,output){
observeEvent(input$change,{
df$title <<- as.character(df$title)
df[input$row,"title"]<-input$newt
})
k <- 0
observeEvent(input$generate, {
insertUI(
selector= "#aux",
where="beforeBegin",
ui = plotOutput(paste0("plot",input$generate))
)
k <- k + input$generate
if(input$generate==1){
df <<- data.frame(title = input$title)
df$title <<- as.character(df$title)
}else{
aux <- data.frame(title = input$title)
df <<- rbind(df,aux)
df$title <<- as.character(df$title)
}
output[[paste0("plot",input$generate)]] <- renderPlot(
plot(rnorm(100), main = df[k,"title"])
)
})
}
shinyApp(ui,server)
Upvotes: 1
Views: 2505
Reputation: 84519
Put the renderPlot
inside the observer:
library(shiny)
ui <- fluidPage(
textInput("title","Title",""),
actionButton("generate","Plot"),
div(id="aux")
)
server <- function(input,output){
observeEvent(input$generate, {
insertUI(
selector= "#aux",
where="beforeBegin",
ui = plotOutput(paste0("plot",input$generate))
)
output[[paste0("plot",input$generate)]] <- renderPlot(
plot(rnorm(100), main = isolate(input$title))
)
})
}
shinyApp(ui,server)
Solution for the edited question:
library(shiny)
ui <- fluidPage(
column(6,
textInput("title","Title",""),
actionButton("generate","Plot"),
div(id="aux")),
column(6,
textInput("newt","New title",""),
selectInput("row","Row",choices=c(1:10)),
actionButton("change","Change title"))
)
server <- function(input,output){
titles <- reactiveValues()
observeEvent(input$change, {
titles[[input$row]] <- input$newt
})
values <- replicate(10, rnorm(100))
for(i in 1:10){
local({
ii <- i
output[[paste0("plot",ii)]] <- renderPlot(
plot(values[,ii], main = titles[[as.character(ii)]])
)
})
}
observeEvent(input$generate, {
titles[[as.character(input$generate)]] <- input$title
insertUI(
selector = "#aux",
where = "beforeBegin",
ui = plotOutput(paste0("plot",input$generate))
)
})
}
shinyApp(ui,server)
Upvotes: 2