How to show ggplot from external function in shiny R application? - r

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.

Related

R - using shinytest with rhandsontable when table uses hot_validate_*

I am trying to create automated tests for a shiny app that uses rhandsontable. The rhandsontable uses hot_validate_numeric functions, and when running the app via shinytest, the rhandsontable does not render (when I try taking a screenshot of the running app), and if I call any computation in the app that depends on said rhot table, the app crashes.
A simple reproducible example where I display mtcars as a rhot table, and a button that computes mean of mpg using the data from the rhot table.
library(shiny)
library(rhandsontable)
# Define UI for application that draws a histogram
ui <- fluidPage(
titlePanel("Test"),
fluidRow(column(12, rHandsontableOutput("input_table"))),
actionButton("button", "Compute MPG Mean"),
textOutput("mean")
)
# Define server logic required to draw a histogram
server <- function(input, output) {
output$input_table <- renderRHandsontable(
rhandsontable(mtcars) %>% hot_validate_numeric("mpg", min = 0, max = 40)
)
observeEvent(
input$button, {
n = mean(hot_to_r(input$input_table)$mpg)
output$mean = renderText(n)
}
)
}
# Run the application
shinyApp(ui = ui, server = server)
Now if I run the tests in the following manner, the app crashes:
app <- ShinyDriver$new("path/to/app")
app$takeScreenshot() # rhot table does not appear in this
app$setInputs(button = "click")
# I get a message saying : Server did not update any output value within 3 seconds
# And if take another screenshot of app, I can see the app has crashed.
The app works normally, it only fails when using shinytest. If I remove hot_validate_numeric, then shinytest works too.
Is there some way I can use hot_validate_numeric and still be able to run tests?

ggplot histogram fails inside shiny app

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.

D3partitionROutput non-reactive to changing output

D3partitionR has some fantastic visualisations for hierarchical and sequential data, however it seems to have a major flaw in Shiny.
The D3partitionROutput function (& renderD3partitionR) don't update the plotted object when the output object is updated.
The functions work perfectly on first execution of a graph however the plotted objects can't be reactively updated.
Does anyone know of a fix or workaround as I really like this package's visualisations?
library(shiny)
library(D3partitionR)
path_in=list(list("A","B","C","D"),list("A","B","F","G"),list("A","D"),list("A","B","END"))
value_in=c(15,29,21,34)
# Define UI for application that draws a histogram
ui <- fluidPage(
# Application title
titlePanel("Old Faithful Geyser Data"),
# Sidebar with a slider input for number of bins
sidebarLayout(
sidebarPanel(
selectInput("type_in",
"Plot type:",
choices = c('circleTreeMap', 'partitionChart', 'treeMap')
)
),
# Show a plot of the generated distribution
mainPanel(
D3partitionROutput("part_out")
)
)
)
# Define server logic required to draw a histogram
server <- function(input, output) {
output$part_out <- renderD3partitionR({
type = input$type_in
D3partitionR(data=list(path=path_in,value=value_in)
, type = type)
})
}
# Run the application
shinyApp(ui = ui, server = server)
Update:
I found a similar bug here in Rwordcloud that was resolved by modifying the "render" function in Rwordcloud.js. I looked into renderValue in D3partitionR.js and the function doesn't take an input of 'instance' (as is done in Rwordcloud.js) so it seems it doesn't know when to delete / refresh renderValue. I'm an R guy (and have no js experience) so I don't know how the renderValue function should be changed in D3partitionR.js however I'm pretty sure this is the source of the problem.. Help!

How to display a grid.table with Shiny

I want to display a dataframe in a table using grid.table(myDataFrame). I need help figuring out:
what output* and render* functions to use with shiny
what to write exactly in the render* function body
This far I have the following codes
In the UI.R, inside fluidPage and fluidRow:
dataTableOutput("TauxInsertion")
And then in Server.R:
output$TauxInsertion <- renderDataTable({
dataDepartement()
# TauxInsertionTable <- grid.table(dataDepartement())
# TauxInsertionTable
})
dataDepartement is a reactive variable that contains a dataFrame. Returning this data frame inside the renderDataTable gives me a table. But I need to be able to display the row names and add some color and style to the display. The commented part is what I have tried but doesn't display anything.
There are no significant messages in the console. I have also tried options(shiny.trace=TRUE) but to no avail.
I think you have to use functions dedicated to plot. Take a look
library(shiny)
library(grid)
library(gridExtra)
ui <- fluidPage(
plotOutput("plot")
)
server <- function(input, output) {
output$plot <- renderPlot({
grid.table(head(iris,3))
})
}
shinyApp(ui = ui, server = server)

How to render scatter3d inside shiny page instead of popup

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:

Resources