How can I reset the graph to display a blank plot? I've created a reset button and have tried various recommendations, but they usually cause some sort of problem or they do nothing at all.
ui <- fluidPage(
theme = shinytheme("cerulean"),
navbarPage( "Unemployment Rate Comparison Tool",
tabPanel("Interactive Graph",
titlePanel("US Unemployment Rates Before and After COVID-19"),
sidebarLayout(
sidebarPanel(
selectInput(
inputId = "y",
label = "Select State(s) to Graph",
choices = unique(q_long$State),
selected = "United States",
multiple = TRUE
), # select input end
radioButtons(
inputId = "x",
label = "Displaying Unemployment Rates for 2013-2022",
choices = c("Year"),
selected = "Year"
), # Radio buttons end
actionButton("run_plot", "Run Plot"),
actionButton("reset", "Clear Output"),
), # side bar panel end
mainPanel(
span(strong("Compare State Unemployment Rates Pre and Post COVID.", style = "color:black"),style = "font-si16pt"),
div("Select the state(s) you wish to view from the drop down menu. Once you have made your selections, click \"Run Plot\"."),
br(),
plotlyOutput(outputId = "graph"),
) # Main panel end
) # select input end
), #navbar interactive graph
tabPanel("Data", DT::dataTableOutput(outputId="datasheet"))# navbar data end
) #Navbar end
) # fluid page end
server <- function(input, output, session) {
q_filtered <- eventReactive(input$run_plot, {
filter(q_long, State %in% input$y)
})
output$graph <- renderPlotly({
ggplot(q_filtered(), aes(x = .data[[input$x]], y = unemployment, color = State)) + geom_point() + geom_line() + geom_vline(aes(xintercept = 2020)) + scale_x_continuous(breaks = q$year)
}) # render plotly end
output$datasheet<-DT::renderDataTable({
DT::datatable(data=q,
rownames=FALSE)}
)
} # server end
shinyApp(ui = ui, server = server)
I am just really not sure what to do from here
Maybe like this (not tested):
server <- function(input, output) {
Plot <- reactiveVal()
q_filtered <- eventReactive(input$run_plot, {
filter(q_long, State %in% input$y)
})
observe({
gg <- ggplot(q_filtered(), aes(x = .data[[input$x]], y = unemployment, color = State)) + geom_point() + geom_line() + geom_vline(aes(xintercept = 2020)) + scale_x_continuous(breaks = q$year)
Plot(gg)
})
observeEvent(input$reset, {
Plot(plotly_empty())
})
output$graph <- renderPlotly({
Plot()
})
output$datasheet <- DT::renderDataTable({
DT::datatable(data=q,
rownames=FALSE)}
)
} # server end
Related
I am currently trying to make an interactive app on shiny where with my data frame "keep_df" you can choose which kind of plot you want to use and for the x and y axes you can choose any of the columns from keep_df. Below is my code. I'm not getting any error messages, but the code is not running as desired. I was wondering if anyone had any suggestions. Thanks!
ui <- navbarPage ("Title",
tabPanel("Chart builder",
sidebarLayout(
sidebarPanel(
pickerInput(inputId = 'chart', label = '1. Select chart type', choices = c("Scatter plot", "Bar chart", "Histogram", "Pie chart", "Box plot"), selected = NULL, multiple = FALSE),
pickerInput(inputId = 'xaxis', label = '2. Select X-axis', choices = colnames(keep_df), selected = NULL, multiple = FALSE),
pickerInput(inputId = 'yaxis', label = '3. Select Y-axis', choices = colnames(keep_df), selected = NULL, multiple = FALSE),
uiOutput("picker2"),
actionButton("view", "View selection"),
),
mainPanel(ui <- DT::dataTableOutput("charttable"), plotOutput("plots")),
)
)
)
server <- function(input, output, session) {
data <- reactive(
keep_df
)
plots <- reactive({
if (input$chart == 'Scatter plot') {
ggplot(data(), aes(x = input$xaxis, y = input$yaxis)) +
geom_point(colour = "black")
}
if (input$chart == 'Bar chart') {
ggplot(data(), aes(x = input$xaxis, y = input$yaxis)) +
geom_point(colour = "black")
}
})
output$plots <- renderPlot(
plots()
)
}
You were pretty close with your code, I noticed a few issues. First, you have an extra ui <- which I could see causing an error. Second, in the plots reactive, where you had x = input$xaxis, it would send a string to the ggplot, rather than a variable. Meaning it wouldn't read the column. I also made the plots reactive as an if and else if, rather than two if statements. Hope this helps!
Note that I didn't have the dataframe, so I just used mtcars for simplicity. There were a few lines I blocked out too. I also added the library and the shinyApp call too, since it wasn't in your example.
library(shiny)
library(ggplot2)
library(shinyWidgets)
keep_df<-mtcars #Don't have the data, just using mtcars
ui <- navbarPage ("Title",
tabPanel("Chart builder",
sidebarLayout(
sidebarPanel(
pickerInput(inputId = 'chart', label = '1. Select chart type', choices = c("Scatter plot", "Bar chart", "Histogram", "Pie chart", "Box plot"), selected = NULL, multiple = FALSE),
pickerInput(inputId = 'xaxis', label = '2. Select X-axis', choices = colnames(keep_df), selected = NULL, multiple = FALSE),
pickerInput(inputId = 'yaxis', label = '3. Select Y-axis', choices = colnames(keep_df), selected = NULL, multiple = FALSE)#,
# uiOutput("picker2"), #Not doing anything
# actionButton("view", "View selection") #Not doing anything
),
mainPanel(DT::dataTableOutput("charttable"), plotOutput("plots")), #Removed the ui <-
)
)
)
server <- function(input, output, session) {
data <- reactive(
keep_df
)
plots <- reactive({
if (input$chart == 'Scatter plot') {
#without the eval(parse(text =)), it reads as string, not variable
ggplot(data(), aes(x = eval(parse(text = input$xaxis)), y = eval(parse(text = input$yaxis)))) +
geom_point(colour = "black")
} else if (input$chart == 'Bar chart') {
ggplot(data(), aes(x = eval(parse(text = input$xaxis)), y = eval(parse(text = input$yaxis)))) +
geom_boxplot(colour = "black")
}
})
output$plots <- renderPlot(
plots()
)
}
shinyApp(ui, server)
I'm creating an Rshiny with two tabs. The data is a list of students, and the plots/tables are to be filtered through the input of grade selection on a drop-down list. The table I have on tab one is working fine, but everything I have tried to do to connect the last two plots on the second tab to the input are not working. Now I have it to where it is just showing totals without using the input filter of grade. Can anyone detail how to connect my input to both output plots? I'll put my code below
library(shiny)
library(tidyverse)
students = read.csv("C:/Users/j062d273/Downloads/RShiny Grade EX.csv",
stringsAsFactors = FALSE)
# Define UI for application that draws a histogram
ui <- fluidPage(
# Application title
headerPanel("Student Data"),
# tabs set up
tabsetPanel(
tabPanel(title = "Students by Grade",
mainPanel(width = 12, align = "center",
selectInput("grade", "Select Grade", choices=unique(sort(students$Grade,
decreasing = FALSE)), selected = 1),
submitButton("Go"),
tags$h3("Student List"),
div(style = "border:1px black solid;width:80%",tableOutput("student_list"))
)),
tabPanel(title = "Trends by Grade",
mainPanel(width = 12,align = "center",
div(style = "float:left;width:36%;",plotOutput("male_fem_dist")),
div(style = "float:right;width:64%;",plotOutput("ethnicity_plot")))
)))
# Define server logic required to draw plot
server <- function(input, output) {
output$student_list <- renderTable({
gradefilter <- subset(students, students$Grade == input$grade)
})
output$male_fem_dist <- renderPlot({
ggplot(students, aes(x=Gender)) +
geom_bar(fill = "blue", color = "red") +
ggtitle("Gender Count by Selected Grade")
})
output$ethnicity_plot <- renderPlot({
ggplot(students, aes(x=Ethnicity)) +
geom_bar(fill = "red", color = "blue") +
ggtitle("Ethnicity Count by Selected Grade")
})
}
# Run the application
shinyApp(ui = ui, server = server)
Filter the dataset first, and then use it in both table and plot.
Try this
server <- function(input, output) {
gradefilter <- reactive({subset(students, students$Grade == input$grade)})
output$student_list <- renderTable({gradefilter()})
output$male_fem_dist <- renderPlot({
ggplot(gradefilter(), aes(x=Gender)) +
geom_bar(fill = "blue", color = "red") +
ggtitle("Gender Count by Selected Grade")
})
output$ethnicity_plot <- renderPlot({
ggplot(gradefilter(), aes(x=Ethnicity)) +
geom_bar(fill = "red", color = "blue") +
ggtitle("Ethnicity Count by Selected Grade")
})
}
Issues between inputs and plot output
Hi,
I'm testing out a basic ShinyApp where I can generate a plot of commercial services broken down by geography and service type.
The idea is I want the user to use three drop-down menu inputs, each dependent upon the previous selection, to subset the data, which then gets output in a ggplot.
However, I'm having issues connecting the inputs to the plot output (see below). The inputs are working fine and reactive when selected, but I can't work out how to link that to the plot, I get the feeling I'm not using the right data source (but have no idea how to ensure it is). Furthermore, I'm not familiar with how I would go about adding a third filter (for "service") seeing as I don't know how to link my data source in the first place.
Sorry this is probably simple, but some help would be really appreciated.
UI
#Data
Test <- dataframe(
Geography1 = c("Region","Local Authority","County"...),
Geography2 = c("North West","Aldershot","Cheshire"...),
Service = c("Shop","Cafe","Library"...),
Overall_rating = c("Awesome","Good","Fantatstic"...),
Locations = c(4000, 1300, 1700...)
)
#SHINY APP
ui <- fluidPage(
titlePanel("Tool"),
sidebarLayout(
sidebarPanel(
uiOutput("geography1"),
uiOutput("geography2"),
uiOutput("service")),
mainPanel(
plotOutput("plot", height = "400px"))
)
)
Server
server <- function(input, output) {
output$geography1 = renderUI({
selectInput(inputId = "geog1",
label = "Geography 1:",
choices = as.character(unique(Test$Geography1)),
selected = "Region")
})
output$geography2 = renderUI({
datasub <- Test[Test$Geography1 == input$geog1, "Name"]
selectInput(inputId = "geog2",
label = "Geography2:",
choices = unique(datasub),
selected = unique(datasub)[1])
})
output$service = renderUI({
datasub2 <- unique(datasub)
selectInput(inputId = "service",
label = "Service type:",
choices = unique(...),
selected = unique(...)[1])
})
output$plot = renderPlot({
ggplot(datasub2(),aes(x = Overall_rating, y = Locations, fill= Overall_rating))+
geom_bar(stat = "identity")
})
}
shinyApp(ui, server)
It's hard to tell how the provided data is supposed to be filtered in the app but this code will at least run and be interactive. Hopefully from there you can figure out how to adjust the dataset.
As BigDataScientist said one fault is that you're not using a reactive dataset.
#Data
Test <- data.frame(
Geography1 = c("Region","Local Authority","County"),
Geography2 = c("North West","Aldershot","Cheshire"),
Service = c("Shop","Cafe","Library"),
Overall_rating = c("Awesome","Good","Fantatstic"),
Locations = c(4000, 1300, 1700)
)
#SHINY APP
ui <- fluidPage(
titlePanel("Tool"),
sidebarLayout(
sidebarPanel(
uiOutput("geography1"),
uiOutput("geography2"),
uiOutput("service")),
mainPanel(
plotOutput("plot", height = "400px"))
)
)
server <- function(input, output) {
output$geography1 = renderUI({
selectInput(inputId = "geog1",
label = "Geography 1:",
choices = as.character(unique(Test$Geography1)),
selected = "Region")
})
datasub <- reactive({
Test[Test$Geography1 == input$geog1,]
})
output$geography2 = renderUI({
selectInput(inputId = "geog2",
label = "Geography2:",
choices = unique(datasub()[,"Geography2"]),
selected = unique(datasub()[,"Geography2"])[1])
})
datasub2 <- reactive({
datasub()[Test$Geography2 == input$geog2, ]
})
output$service = renderUI({
selectInput(inputId = "service",
label = "Service type:",
choices = unique(datasub2()[,"Service"]),
selected = unique(datasub2()[,"Service"])[1])
})
datasub3 <- reactive({
datasub()[Test$Service == input$service, ]
})
output$plot = renderPlot({
ggplot(datasub3(),aes(x = Overall_rating, y = Locations, fill= Overall_rating))+
geom_bar(stat = "identity")
})
}
shinyApp(ui, server)
So I am using mpg dataset to practice my R-shiny skills, but I encountered a problem.
I want to write a app which I could choose different variables to make graph, if it involves at least one discrete variable, then I draw a geom_boxplot, else, I will just draw a geom_point.
Now I want to add a slider to filter numeric inputs, but how?
My ui.R looks like this:
library(shiny)
shinyUI(fluidPage(
# Application title
titlePanel("Old Faithful Geyser Data"),
# Sidebar with a slider input for number of bins
sidebarLayout(
sidebarPanel(
selectInput(inputId = "var1",
label = "Choose x variable",
choices =
names(mpg)
),
selectInput(inputId = "var2",
label = "Choose y variable",
choices =
names(mpg))
),
# Show a plot of the generated distribution
mainPanel(
plotOutput("distPlot")
)
)
))
And
My server.R looks like this:
server <- function(input,output){
output$distPlot <- renderPlot({
# browser()
if(typeof(mpg[[input$var1]]) == "character")
{
ggplot(mpg) +
xlab(input$var1) +
ylab(input$var2) +
ggtitle(paste("Plot", input$var1, "vs", input$var2)) +
geom_boxplot(mapping =
aes_string(x = input$var1,
y = input$var2))
}
else
{
ggplot(mpg) +
xlab(input$var1) +
ylab(input$var2) +
ggtitle(paste("Plot", input$var1, "vs", input$var2)) +
geom_point(mapping =
aes_string(x = input$var1,
y = input$var2))
}
})
}
Now, how could I add a slider to filter numeric input?
I am a new learner, please help me.
Thank you very much
I'm sorry that I don't have time to flesh out this demo into a better example but hopefully this will show you the methodology:
library(shiny)
library(ggplot2)
library(magrittr)
ui <- fluidPage(
# Application title
titlePanel("Optional Numeric Slider Demo"),
sidebarLayout(
sidebarPanel(
selectInput(inputId = "var1",
label = "Choose x variable",
choices =
names(mpg)
),
uiOutput('Var1Slider'),
br(),
selectInput(inputId = "var2",
label = "Choose y variable",
choices =
names(mpg)[sapply(mpg,class)=="character"])
),
mainPanel(
plotOutput("distPlot")
)
)
)
server <- function(input,output){
output$distPlot <- renderPlot({
if(typeof(mpg[[input$var1]]) == "character")
{
ggplot(mpg) +
xlab(input$var1) +
ylab(input$var2) +
ggtitle(paste("Plot", input$var1, "vs", input$var2)) +
geom_boxplot(mapping =
aes_string(x = input$var1,
y = input$var2))
}
else
{
mpg %>%
dplyr::filter(get(input$var1)>input$Var1Slide[1]) %>%
dplyr::filter(get(input$var1)<input$Var1Slide[2]) %>%
ggplot() +
xlab(input$var1) +
ylab(input$var2) +
ggtitle(paste("Plot", input$var1, "vs", input$var2)) +
geom_point(mapping =
aes_string(x = input$var1,
y = input$var2))
}
})
output$Var1Slider <- renderUI({
if(typeof(mpg[[input$var1]]) == "character"){
return(NULL)
}else{
sliderInput('Var1Slide',
label=paste("selected:",input$var1),
min=min(mpg[[input$var1]]),
max=max(mpg[[input$var1]]),
value=c(min(mpg[[input$var1]]),max(mpg[[input$var1]])),
step = 1)}
})
}
# Run the application
shinyApp(ui = ui, server = server)
The key points are the use of renderUI and uiOutput to move computation to the server side. I've also added a line to the numeric graph code to show how to use the input (even if the edit is nonsensical at the moment). Let me know if anything is unclear.
EDIT:I've changed this example so that the slider values actually filter the data going into the plot.
I have this shiny code and the plot is not showing for some reason. Can you please extend me a hand?
Is a basic shiny plot to render in the Main Panel. Checked loads of times and still not plotting.
library(shiny)
library(plotly)
library(ggplot2)
ui <- fluidPage(
(titlePanel("APP & MEP | Size (m2) ~ Hours", windowTitle = "app")),
sidebarLayout(
sidebarPanel(
checkboxGroupInput(inputId = "checkgroup",
label = "Select Deparments",
choices = c("All", "ELE", "HVAC", "MAN", "PH", "LV"),
selected = "All", inline = F),
radioButtons(inputId = "radio",
label = "ADD Stat_Smooth?",
choices = c("YES","NO"),
inline = T),
sliderInput(inputId = "slider",
label = "SPAN Setting",
min = 0.2, max = 2, value = 1,
ticks = T)
),
mainPanel(plotOutput(outputId = "plot33"))
)
)
server <- function(input, output){
output$plot33 <- renderPlotly({
gg <- ggplot(sizedf, aes(SIZE, Hours)) + geom_point(aes(color = Department)) + ggtitle("Size(m2) vs Hours per department")
p <- ggplotly(gg)
p
})
}
shinyApp(ui = ui, server = server)
I have seen this same mistake a few time already.
plotlyOutput() should be used, not plotOutput()