I am learning how to use Shiny, and I tried to create a very simple barchart in ggplot2, with a dropdown menu, that allows the user to select a class from a school using the dropdown, and it is supposed to create a barchart with exam result percentages on the y-axis and names on the x-axis. The code I have is as follows:
ui = fluidPage(selectInput(inputId = "Class", label = "Pick a Class", choices = levels(fulldata$Class), plotOutput("bar"), multiple = FALSE, selectize = FALSE))
server = function(input, output){
output$bar = renderPlot({
plotdata = reactive({data %>% filter(Class == input$Class)})
ggplot(plotdata(), aes(x = Name, y = Percent_full) + geom_bar())
})
}
shinyApp(ui = ui, server = server)
The end result correctly renders the dropdown menu, but it does not render the plot whatsoever. I have tried changing the ggplot call to a simple hist(rnorm(1000)) but it does not render either.
I solved the problem: the plotOutput function in the fluidPage function was defined as an argument of the input function, not as an argument of fluidPage. It works now!
It might be that your code needs to declare the reactive data before you create your ggplot.
Try this:
plotdata = reactive(
data %>% filter(Class == input$Class)
)
output$bar = renderPlot({
ggplot(plotdata(), aes(x = Name, y = Percent_full) + geom_bar())
})
Here is more example code from a functioning shiny app using reactive data for ggplot:
data <- reactive(
merged_clean_data %>% filter(between(date, as.POSIXct(input$dateRange[1]),
as.POSIXct(input$dateRange[2])))
)
#Output plot for any selected variable
output$timePlot <- renderPlot({
ggplot(data(), aes(x = date, !!input$selection)) +
theme_classic() + geom_line() +
coord_cartesian(xlim = as.POSIXct(ranges$x, origin = "1970-01-01"), expand = FALSE) +
theme(text = element_text(size = 16), axis.title.x=element_blank(), axis.text.y = element_text(angle=90, vjust=1, hjust=1)) + {if(input$hlineadd)geom_hline(yintercept = input$hline)} +
{if(input$smoothingadd)geom_smooth()}
}, res = 80)
I want to display my animated bar plot in R shiny web app. I am getting my animated plot in the Rstudio viewer pane but unfortunately, it is not working in app
CODE:
# LIBRARIES
library(ggplot2)
library(shiny)
library(gganimate)
# LOADING CSV
undergradDATA <- read.csv(file="1-10 Undergraduates.csv", head=TRUE, sep=",")
# UI
ui <- fluidPage (
mainPanel(
plotOutput("myplot")
)
)
# SERVER
server <- function(input, output) {
output$plot <- renderPlot({
undergrad_plot <- ggplot(data=undergradDATA , aes(x=HEI, y=Undergrad), height = 461, width = 644) +
geom_bar(stat='identity', fill="darkolivegreen3", colour="white")
undergrad_plot + ggtitle("Ranking of Top 10 HEI's w.r.t Undergraduates") +
theme(
plot.title = element_text(hjust = 0.5,
colour = "darkolivegreen",
size = 17,
family = "courier"
) )
undergrad_plot + transition_states(Undergrad, wrap = FALSE) +
shadow_mark() +
enter_grow() +
enter_fade()
})
}
# RUNNING APP
shinyApp(UI, server)
Besides some minor flaws in your code (it should be "plot" instead of "myplot" and "ui" instead of "UI" the main issue is that you can't render and output an animated plot via renderPlot and plotOutput. Instead you have to make use of renderImage and imageOutput.
Adapting this answer and making use of some example data created from ggplot2::mpg:
library(ggplot2)
library(shiny)
library(gganimate)
library(dplyr)
## Example data
undergradDATA <- mpg %>%
count(class, sort = TRUE) %>%
mutate(class = reorder(class, n)) %>%
rename(Undergrad = class, HEI = n)
ui <- fluidPage(
mainPanel(imageOutput("plot"))
)
server <- function(input, output) {
output$plot <- renderImage(
{
undergrad_plot <- ggplot(data = undergradDATA, aes(x = HEI, y = Undergrad), height = 461, width = 644) +
geom_bar(stat = "identity", fill = "darkolivegreen3", colour = "white")
undergrad_plot + ggtitle("Ranking of Top 10 HEI's w.r.t Undergraduates") +
theme(
plot.title = element_text(
hjust = 0.5,
colour = "darkolivegreen",
size = 17,
family = "mono"
)
)
anim <- undergrad_plot +
transition_states(Undergrad, wrap = FALSE) +
shadow_mark() +
enter_grow() +
enter_fade()
anim_save("outfile.gif", animate(anim)) # New
# Return a list containing the filename
list(src = "outfile.gif", contentType = "image/gif")
},
deleteFile = TRUE
)
}
shinyApp(ui, server)
My file is one set of game data and PitchNo tells the pitch of the game. I am trying to generate plots of each batter's pitches seen in a game and I have labeled the PitchNo in the ggplot function. I want my plot for each batter to label the pitches seen, say 1-10, but instead it is still labeling them as the PitchNo of the game.
I added Batter$PitchNo <- 1:nrow(Batter) in my reactive filter. That line of code works in normal R but I cannot seem to find a way to make in work in a Shiny app.
library(shiny)
library(tidyverse)
GameDataFile <- read_csv("GameDataFile.csv")
GameDataFile %>% group_by(PitchNo)
playerlist <- sort(unique(GameDataFile$Batter))
ui = fluidPage(
titlePanel("Title"),
sidebarLayout(
sidebarPanel(
selectInput(
inputId="Batter1",
label="Player:",
choices = playerlist)
),
mainPanel(
plotOutput("myZone")
)))
server = function(input, output){
output$myZone <- renderPlot({
GameDataFile$PlateLocSide <- (GameDataFile$PlateLocSide * -1)
newdata <- reactive({
GameDataFile %>% filter(
Batter %in% c(input$Batter1),
Batter$PitchNo <- 1:nrow(Batter)) # Error is here
})
ggplot(data = newdata(), aes(x = PlateLocSide, y = PlateLocHeight)) +
xlim(-2.5,2.5) + ylim(0,5) + scale_fill_viridis_c() + geom_point() +
labs(x = "", y = "") + facet_wrap(~ Batter, ncol = 2) +
geom_text(aes(label = PitchNo), vjust = -0.5) + theme_bw() +
theme(strip.text = element_text(size=20, face="bold"))
}, width=400, height=500)
}
shinyApp(ui = ui, server = server)
I have an issue with a reactive ggplot in Shiny.
necessary packages
library(shiny)
library(ggplot2)
library(ggthemes)
generate a dataset, it contains non-valid names, and the corresponding valid Name
df_pheno<- data.frame(Species = sample(c("Euthycerina pilosa", "Euthycerina pilosa", "Euthycerina pilosa", "Euthycerina vittithorax", "Euthycerina test")),
Number = sample(c("3", "4", "1", "1", "2")),
Date = sample(c("1", "50", "2", "30", "1")))
df_pheno$Number <- as.numeric(as.character(df_pheno$Number))
df_pheno$Date <- as.numeric(as.character(df_pheno$Date))
simple ui
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
selectizeInput('validSpecies', 'Choose species',
choices = df_pheno$Species,
options = list(placeholder = 'select species'))
),
mainPanel(plotOutput("pheno")
)
)
)
a server that generates reactive plot
server <- function(input, output, session) {
output$pheno <- renderPlot({
ggplot(df_pheno, aes(x=Date, y= Species == input$validSpecies, fill = Number)) + geom_tile(color="white", size=0.1)+
scale_fill_gradient(low="light grey", high="red", name="# specimens", breaks=c(0,1,2,3,4,5), labels=c(0,1,2,3,4,">=5"), limits=c(0,5))+ scale_x_continuous(breaks=c(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52), labels=c(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52), limits=c(0,53)) +
coord_equal()+
labs(x=NULL, y=NULL, title="Phenology of this species, per week")+
theme(plot.title=element_text(hjust=0.5))+
theme(axis.ticks=element_blank())+
theme(axis.text.x = element_text(size=7, angle=60)) +
theme(axis.text.y = element_text(size=7, face = "italic")) +
theme(legend.title=element_text(size=8)) +
theme(legend.text=element_text(size=8))
})
}
and run it
shinyApp(ui = ui, server = server)
So what do I want: if you select a certain species in the selectizeInput, you generate a plot with the data of ONLY that specific species.
what is this script doing: if you select a certain species in selectizeInput, it shows you a (very good) plot with two species?!
I do not see my error, although, it is probably quite logic.
Thanks for all your help,
Best wishes,
Jonas
I think that in your server function, in ggplot, you should replace this part
ggplot(df_pheno, aes(x=Date, y= Species == input$validSpecies, fill = Number))
with this
ggplot(data = df_pheno[df_pheno$Species == input$validSpecies,],
aes(x = Date, y = Species, fill = Number))
That is, you should subset the data and not the variable that you map into y.
Also, consider to replace the long sequence: c(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52) with 1:52.
I have a dataset with home values for all 50 states over ~30 years. Columns include State, Year, Value, etc. I am trying to create an interactive Shiny app where the user can select certain states so they will be the only ones displayed in the plot. I have successfully created the plot of all states independently where Year is on the x-axis and Value is on the y-axis, colored by State, and also have successfully subset the dataset so that only one state plots.
I am new to Shiny and having issues having anything other than the Input checkBox feature work in this. Is there something obvious I am missing?
ui <- fluidPage(
checkboxGroupInput(inputId = "state", label = "States", choices = levels(AllData2$STATE),
plotOutput(outputId = "hist")))
server <- function(input, output) {
output$hist <- renderPlot({
plot(data = subset(AllData2, AllData2 == input$state), mapping = aes(x = Date, y = HomeValue,
color = STATE) + geom_line(size=2, alpha=0.8) +
scale_y_continuous(breaks = seq(0, 1000000, 50000)) +
scale_x_continuous(breaks = seq(1975, 2020, 5)) +
ylab("Value in Dollars") + xlab("Year"))
})
}
shinyApp(ui = ui, server = server)
I get no output in my Shiny App except the checkbox options. Thank you for any help.
There are only syntax errors in your code. Many of them:
You have included plotOutput() inside the checkbox group, please place it outside it.
Use ggplot() instead of plot()
You have included everything inside plot() If you use ggplot() the syntax is: ggplot(data=AllData,mapping=aes())+geom_line()+scale_y_continuous()+scale_x_continuous()+labs(x="This is X label",y="This is ylab",color="This is the color legend label")
Your code will work after fixing these problems
Just copy paste this if you want instant result:
library(shiny)
library(ggplot2)
library(dplyr)
ui <- fluidPage(
column(12,checkboxGroupInput(inputId = "state", label = "States", choices = c(1,2,3,4,5))),
column(12,plotOutput(outputId = "hist")))
server <- function(input, output) {
output$hist <- renderPlot({
ggplot(data = subset(AllData2, AllData2$STATE %in% input$state), mapping = aes(x = Date, y = HomeValue,
color = STATE)) + geom_line(size=2, alpha=0.8) +
scale_y_continuous(breaks = seq(0, 1000000, 50000)) +
scale_x_continuous(breaks = seq(1975, 2020, 5)) +labs(x="Value in Dollars",y="Year")
})
}
shinyApp(ui = ui, server = server)