I am trying to make a Shiny App that retrieves an image from Nasa API and displays it to the user.
Although I manage to download the image from the API and store it in a temp file I can't display it in the shiny app but only locally.
Here is my code so far:
library(shiny)
library(httr)
library(jpeg)
library(RCurl)
library(jsonlite)
library(shinythemes)
#library(imager)
key<-"eH45R9w40U4mHE79ErvPWMtaANJlDwNaEtGx3vLF"
url<-"https://api.nasa.gov/planetary/apod?date="
ui <- fluidPage(theme = shinytheme("yeti"),
# Application title
titlePanel("Nasa API"),
sidebarLayout(
sidebarPanel(
helpText("Wellcome to Nasa search API ",
"enter a date in YYYY-MM-DD to search for picture"),
textInput("date", label="Date input",
value = "Enter date..."),
actionButton("go", "Search")
),
mainPanel(
imageOutput("myImage")
)
)
)
server <- function(input, output,session) {
query<-eventReactive(input$go,{
input$date
})
output$myImage <- renderImage({
nasa_url<-paste0(url,query(),"&api_key=",key)
# A temp file to save the output.
# This file will be removed later by renderImage
response<-getURLContent(nasa_url)
json<-fromJSON(response)
img_url<-json$url
temp<-tempfile(pattern = "file", fileext = ".jpg")
download.file(img_url,temp,mode="wb")
jj <- readJPEG(temp,native=TRUE)
plot(0:1,0:1,type="n",ann=FALSE,axes=FALSE)
rasterImage(jj,0,0,1,1)
#im<-load.image(temp) #use this with library(imager)
#plot(im) #use this with library(imager)
},deleteFile = T)
}
# Run the application
shinyApp(ui = ui, server = server)
Be careful when sharing your code as you just shared your private API key. I suggest you generate a new one.
It does not work because shiny only serves files that are in the ~/www directory. So they should be downloaded to that folder for your method to work.
Perhaps an easier way to go about this is simply to embed the image. Looking at the code it looks like json$url is the URL to the image.
library(shiny)
ui <- fluidPage(
h4("Embedded image"),
uiOutput("img")
)
server <- function(input, output, session) {
output$img <- renderUI({
tags$img(src = "https://www.r-project.org/logo/Rlogo.png")
})
}
shinyApp(ui, server)
You could try the above without hardcoding https://www.r-project.org/logo/Rlogo.png and using your json$url instead.
Related
In my shiny server I am figuring out the name of a markdown file which I want to show in the UI. I know how to pass the file name, as a string, back to the UI but I don't now how to tell includeMarkdown() to treat the string as a file name.
My code so far is below. Any advice?
library(shiny)
fileConn<-file("hello.md")
writeLines(c("# Hello","# World"), fileConn)
close(fileConn)
ui <- fluidPage(
includeMarkdown("hello.md"),
br(),
div("File name text:", textOutput("fileNameText", inline = TRUE)),
#includeMarkdown(fileNameText) # this needs help
)
server <- function(input, output, session) {
selectedName <- reactive({
paste0("hello.md") # this is actually more complicated...
})
output$fileNameText <- renderText(
paste0(selectedName())
)
}
shinyApp(ui = ui, server = server)
Your example code works fine, but from your description, I am thinking your asking how to pass a different filename to includeMarkdown() that was created somewhere else in the app, correct?
The first step is to understand includeMarkdown() as a UI element that will change depending on other UI elements (and stuff that happens in server). The solution is to use a placeholder in the ui to hold the place for the includeMarkdown() element, and create that particular element in server using renderUI.
Hopefully you can follow this example. I'm using uiOutput('displayFile') to hold the place for the element that's created in server.
library(shiny)
fileConn<-file("hello.md")
writeLines(c("# Hello","# World"), fileConn)
close(fileConn)
fileConn1<-file("goodbye.md")
writeLines(c("# Goodbye","# Everyone!"), fileConn1)
close(fileConn1)
ui <- fluidPage(
selectInput('file_selection', 'Choose Markdown File:', choices=c('hello.md','goodbye.md')),
uiOutput('displayFile')
)
server <- function(input, output, session) {
output$displayFile <- renderUI({
includeMarkdown(input$file_selection)
})
}
shinyApp(ui = ui, server = server)
I have met an issue when I try to implement a download button in Shiny App. Every time I run the app, it will only show me an HTML file not the actual content file. Here is my code for both the server and UI parts.
library(shiny)
library(reticulate)
shinyServer(function(input,output){
reticulate::source_python("function.py")
data_xi <- run_xi(26)
output$downloadData <- downloadHandler(
filename = function(){
paste(Sys.time(), 'site_mtx.xlsx')
},
content = function(file){
write_xlsx(data_xi, file)
}
)
})
Here is the UI:
library(shiny)
shinyUI(fluidPage(
downloadButton("downloadData", "Download Metrics Reports")
))
I just tried to use the reticulate function in my python file and save the processed dataframe to Shiny App which can be downloads, thank you very much!
I ran an example out of your code with some adjustions (unfortunately i don't have your file) and it downloads normally a xlsx file. Add the data.frame( run_xi(26))and if this is not the problem maybe the "writexl" library can be the solution.
Hope it will help.
library(shiny)
library(reticulate)
library(writexl)
if (interactive()) {
ui <-fluidPage(
downloadButton("downloadData", "Download Metrics Reports")
)
server <- function(input,output){
data_xi <- data.frame(s = c(1:3),r = c(4:6), x =c(19:21))
output$downloadData <- downloadHandler(
filename = function(){
paste(Sys.time(), 'site_mtx.xlsx')
},
content = function(file){
write_xlsx(data_xi, file)
}
)
}
shinyApp(ui, server)
}
I am not good at English, so sentences may be wrong.
I want to distribute excel files prepared in advance to users. Is it possible to realize such a system with shiny? No problem with .zip.
Thank you
ui.R
shinyUI(
fluidPage(
downloadButton('downloadData', 'Excel Download')
)
)
server.R
shinyServer(function(input, output) {
output$downloadData <- downloadHandler(
filename = "distribution.xlsx",
content = "distribution_excel"
)
})
Yes, it is possible and you were nearly there. Below is a minimal working example. I assume that your .xlsx file is located in the same folder as your app.R. Notice that I have created the app in a single R file as opposed to two separate files.
The trick to getting the file to download is to use a function for the content inside of downloadHandler(). Specifically we are using the base function file.copy(). Clicking the button should now download the file: distribution.xlsx. This file can obviously be exchanged with a zip file.
If you want different users to access different Excel files, you can write an additional function inside of your server function that passes the file argument to the downloadHandler().
# Load packages ----
pkgs <- c("shiny")
invisible(lapply(pkgs, require, character.only = TRUE))
# Set up the UI ----
ui <- fluidPage(
# Define your download button
downloadButton(
outputId = "downloadData",
label = "Excel Download"
)
)
# Set up the server side ----
server <- function(input, output, session) {
# Define the download handler with function() for content.
output$downloadData <- downloadHandler(
filename = "distribution.xlsx",
content = function(file) {
file.copy("distribution.xlsx", file)
}
)
}
# Combine into an app ----
shinyApp(ui = ui, server = server)
I am almost done creating a survey using Rshiny. I want to create a button that will allow the user to upload an image (jpeg,tiff,png etc) to the R shiny server, Dropbox, or google drive. It seems the fileInput method only accepts documents like csv? any help would be appreciated!
fileInput actually allows the import of any type of files. You just need to set the argument accept to NULL or to any file extension that you accept. What you need to understand first, is that if you use fileInput, it will actually upload your file to the tmp folder (the path to the uploaded data is stored in input$file$datapath), and only then you will be able to upload your file to googledrive or to whatever cloud. A solution using fileInput could look like this:
library(googledrive)
ui <- fluidPage(
fileInput(inputId = "file",
label = "Choose file to upload",
accept = NULL)
)
server <- function(input, output) {
observeEvent(input$file, {
drive_upload(media = input$file$datapath,
name = input$file$name)
})
}
shinyApp(ui, server)
If the "double upload" is a problem for you, you can avoid this by using the package shinyFiles. A nice answer has been posted here and here's a way to adapt the code to address your specific problem.
library(googledrive)
library(shinyFiles)
ui <- fluidPage(
shinyFilesButton("Btn_GetFile", "Choose file to upload" ,
title = "Please select a file:", multiple = FALSE,
buttonType = "default", class = NULL)
)
server <- function(input, output, session) {
volumes = getVolumes()
observe({
shinyFileChoose(input, "Btn_GetFile", roots = volumes, session = session)
if (!is.null(input$Btn_GetFile)){
file_selected <- parseFilePaths(volumes, input$Btn_GetFile)
drive_upload(media = as.character(file_selected$datapath),
name = as.character(file_selected$name))
}
})
}
shinyApp(ui = ui, server = server)
I am new to shiny and was wondering if there is a way to display a pdf file generated in "downloadHandler"?
I am using a package to do some biological analysis, and I can make it create a pdf file in downloadHandler. However, I am still struggling if I can view this pdf instead of downloading it.
This question is related to Shiny to output a function that generates a pdf file itself.
Please see the below for the code that works for downloading the pdf output. Thanks so much!
library(shiny)
library(msa)
runApp(list(
#Load the exmaple from the msa package.
mySequenceFile <- system.file("examples", "exampleAA.fasta", package="msa"),
mySequences <- readAAStringSet(mySequenceFile),
myFirstAlignment <- msa(mySequences),
# A simple shiny app.
# Is it possible to see the generated pdf file on screen?
ui = fluidPage(downloadButton('downloadPDF')),
server = function(input, output) {
output$downloadPDF = downloadHandler(
filename = 'myreport.pdf',
content = function(file) {
msaPrettyPrint(
myFirstAlignment
, file = 'myreport.pdf'
, output="pdf"
, showNames="left"
, showLogo="top"
, consensusColor="BlueRed"
, logoColors="accessible area"
, askForOverwrite=FALSE)
file.rename("myreport.pdf", file) # move pdf to file for downloading
},
contentType = 'application/pdf'
)
}
))
If you intend to display the pdf, you should not use downloadHandler. Instead, just use your pdf printing function to generate the pdf file, but the key is
Create a www folder under your Shiny project root
Point the file argument of msaPrettyPrint to www/myreport.pdf
Dynamically add an iframe to display the file. Note in the iframe you point to myreport.pdf directly without www, as Shiny automatically looks for static/media files inside the www folder.
See below for a working example (note I am not using the msa package here but the idea should be the same).
library(shiny)
ui <- shinyUI(fluidPage(
titlePanel("Old Faithful Geyser Data"),
sidebarLayout(
sidebarPanel(
actionButton("generate", "Generate PDF")
),
mainPanel(
uiOutput("pdfview")
)
)
))
server <- shinyServer(function(input, output) {
observeEvent(input$generate, {
output$pdfview <- renderUI({
pdf("www/myreport.pdf")
hist(rnorm(100))
dev.off()
tags$iframe(style="height:600px; width:100%", src="myreport.pdf")
})
})
})
shinyApp(ui = ui, server = server)