I am trying to plot a simple histogram inside a shiny app. Outside the app (in R script), the graph gets plotted without any problems, (see here) but the same code produces an odd looking graph from inside the app (see the wrong graph here)
Could you help me figure out what's wrong? Link to dataset: https://drive.google.com/open?id=1ITK0lTWm_mkb9KonHLq4nuKDv-PBUDeR
library(ggplot2)
library(ggthemes)
library(scales)
library(shiny)
# read data
cso_corruption <- read.csv("cso_corruption.csv", header = T, sep = ",")
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
radioButtons(inputId = "x",label ="Measurement Type",choices =
c("freq_business", "freq_cso"), selected = NULL)
),
mainPanel(
plotOutput(outputId = "hist")
)
)
)
server <- function(input, output) {
output$hist <- renderPlot(ggplot(data = na.omit(cso_corruption), aes(x=input$x)) +
geom_histogram(fill="lightgreen", stat="count"))
}
shinyApp(ui = ui, server = server)
Possible reason is the data is not making it into the server.
I would put the csv into another file within the directory, so you can access it using
read.csv("./Data/projectdata.csv")
Therefore it does not get lost when you publish. Also make sure the data is checked when publishing. One last note to include the read.csv function in the server.
After many trial-and-errors, I have figured out a solution. The trick is, in the server, I used aes_string instead of aes. I haven't figured out why aes_string works here, since it is supposed to require the variables to be passed in quotes. But it works for some reason.
Related
I need to create shiny app which will create a plot basing on dropdown menu choise. The whole computation part is pretty complicated and so is the plot – I created a function which is returning ggplot and I just wanted to show it in the app.
My idea looks as follows:
library(shiny)
source('Analysis/function_external.R')
list_names = c('a', 'b', 'c')
ui <- fluidPage(
selectInput("data", "Select data to plot", choices = list_names)
)
# Define server logic required to draw a histogram
server <- function(input, output) {
observe({function_external(input$data)})
}
# Run the application
shinyApp(ui = ui, server = server)
It is making function run every time I change the input, but it does not show anything. I would really appreciate if you can point me into good direction.
output$my_complicated_plot <- renderPlot({ function_external(input$data) })
Solved the issue.
I am trying to run my shiny application on shiny Server.
At this point I cannot understand the way that shiny server works, I mean I have two R scripts, the ui.R and the server.R inside the shiny server I have this vector. Please refer the code below
#server.R
v_outcome <- c("Confirmados", "Hospitalizados", "Intubado",
"Muertes", "Pruebas", "Síntomas", "UCI")
server <- function(input, output, session) {
# DASHBOARD PAGE ----------------------------------------------------------
#Confirmados
output$confirmados <- renderValueBox({
valueBox(
#paste0(25 + input$count, "%"), "Confirmados", icon = icon("list"),
#color = "purple",
paste0(confirmedNacional),
subtitle = "Confirmados",
icon = icon("fas fa-plus-square"),
color = "yellow",
)
})
This is just a small chunk of my script what I don´t understand is why when I run server.R the script cannot read the vector in the first line, even I tried to add the vector inside the function server but is not working. Which is the way that I need to append my vector?
Thank you
After a long search, this page was very useful https://shiny.rstudio.com/articles/scoping.html
This was my solution:
I created a file called global.R inside this file I declared all the vectors that my UI and my server use.
I have a shiny app (bundled as part of a package) where at the beginning of the server function I create a bunch of reactive data frames that later get used in other parts of the app.
Since quite a few dataframes get created, I wanted to make a simple setup_data() function that could be called at the beginning, in order to help keep the app code tidy. However, since the dfs are created inside a function, I need to use either <<- or assign to make sure they're available in Shiny's server environment.
library(shiny)
setup_data <- function(){
reactiveDat1 <<- shiny::reactiveValues()
reactiveDat1$mydf <<- data.frame(x = 1, y = 2)
reactiveDat2 <<- shiny::reactiveValues()
reactiveDat2$mydf <<- data.frame(x = 5, y = 10)
}
ui <- fluidPage(
titlePanel(""),
sidebarLayout(
sidebarPanel(
),
mainPanel(
)
)
)
server <- function(input, output) {
setup_data()
# rest of app goes here....
}
# Run the application
shinyApp(ui = ui, server = server)
Doing it this way generates a cran NOTE of no visible binding for '<<-' assignment, and in general it is bad practise to do global assigns in a cran package.
Therefore, is there way I can create a function that does the setup like this, but in a way conducive to shiny and cran packages? Ideally I'd like to avoid returning everything in a list, and I haven't found a way to make this work in the Shiny Modules framework as there is no corresponding UI to tie these to.
Is there any other options?
You can setup the data using the global.R file. Any R objects that are created in the global.R file become available to the app.R file, or the ui.R and server.R files respectively. Take a look at how to modularize shiny apps.
EDIT: As pointed out in the comments, you can use local = TRUE to only load objects into the shiny environment.
I'm building a shiny app that is supposed to show a bupaR process_map, which is kind of working.
Sadly the process_map()-function returns a dgr_graph-object, which can't be rendered with the DiagrammeR::renderGrViz() or DiagrammeR::renderDiagrammeR() functions. I found a way to convert it to a grViz / htmlwidget-object with render_graph(), but this way the graph is not nicely scaled. This is especially bad since I'm dealing with very long linear graphs.
Here is a MWE:
# server.R
library(DiagrammeR)
library(bupaR)
shinyServer(
function(input, output) {
plot <- patients %>%
process_map(rankdir = "TB",
render = FALSE)
output$diagram <- renderGrViz({
render_graph(plot)
})
}
)
# ui.R
library(DiagrammeR)
shinyUI(fluidPage(
titlePanel("DiagrammeR + shiny"),
grVizOutput(outputId = "diagram")
))
Is there a better way of displaying a dgr_graph-object in shiny, that fills out the whole width of the app and not just a post-stamp size in the middle? Ideal would be something adaptive, without the need for a fixed width in pixels.
As it turns out the problem is not the render_graph-function on the Server, but rather the default setting of the renderGrViz-function in the UI. When you set it to grVizOutput(outputId = "diagram", height = "100%") it works just fine.
I'm looking at implementing 3D interactive plots in my shiny App, and so far I've been using plotly. However, plotly has one major disadvantage, it's extremely slow when rendering.
I've done checks, and the whole creation of updated outplot$plot <- renderPlotly ({.....}) and plotlyOutput("plot") takes less than 0.5 seconds, despite the large data set involved. This is a know issue for years but still seems to be current.
Hence, I'm looking to use a package called car, also because it has many options, some which I particularly want that are not available in other packages. Info on the car package is here: http://www.sthda.com/english/wiki/amazing-interactive-3d-scatter-plots-r-software-and-data-visualization
The problem is that it renders in a separate popup window rather than inside the shiny app, and I want to have it inside it, or even better, add a button that allow the user to have it as a popup, but only when asked. However, i can't figure out how to jam the bugger into the actual shiny page.
Here is my minimal example with a single text element and the graph code that (in my case) keeps appearing in a separate window rather than in the app.
install.packages(c("rgl", "car", "shiny"))
library("rgl")
library("car")
library(shiny)
cars$time <- cars$dist/cars$speed
ui <- fluidPage(
hr("how do we get the plot inside this app window rather than in a popup?"),
plotOutput("plot", width = 800, height = 600)
)
server <- (function(input, output) {
output$plot <- renderPlot({
scatter3d(x=cars$speed, y=cars$dist, z=cars$time, surface=FALSE, ellipsoid = TRUE)
})
})
shinyApp(ui = ui, server = server)
There is also this package, scatterplot3d but that's not interactive
http://www.sthda.com/english/wiki/scatterplot3d-3d-graphics-r-software-and-data-visualization
And there are some RGL packages but they have the same issue (seperate window) and don't offer the options I am lookign for.
You need to use an rglwidget which takes the last rgl plot and puts in in an htmlwidget. It used to be in a separate package, but it has recently been integrated into `rgl.
Here is the code to do this:
library(rgl)
library(car)
library(shiny)
cars$time <- cars$dist/cars$speed
ui <- fluidPage(
hr("how do we get the plot inside this app window rather than in a popup?"),
rglwidgetOutput("plot", width = 800, height = 600)
)
server <- (function(input, output) {
output$plot <- renderRglwidget({
rgl.open(useNULL=T)
scatter3d(x=cars$speed, y=cars$dist, z=cars$time, surface=FALSE, ellipsoid = TRUE)
rglwidget()
})
})
shinyApp(ui = ui, server = server)
Yielding this: