5

I am still learning R and thus would request the experts in this platform to help me out.

I am trying to create a slideshow of .jpg images in a panel in Shiny. The below code when I run in RStudio gives me the slideshow in the Plot window of RStudio.

folder <- "D:/Photos/Foreign Trips/2014_07_08_USA_Irvine/JulyAugust/" 
file_list <- list.files(path=folder, pattern="*.jpg", full.names = TRUE)
for (j in 1:30) {
        myJPG <- stack(file_list[[j]])
        plotRGB(myJPG)
}

But, when I try to put the same code in server.R and try to call through ui.R, I don't get the slideshow or any image getting displayed. I am getting a blank page when I click on the tab "Photo Slides". I tried using renderUI, renderImage and renderPlot but none works.

ui.R

tabPanel("Photo Slides",
plotOutput("trvImg")
),

server.R

output$trvImg <- renderPlot({
folder <- "D:/Photos/Foreign Trips/2014_07_08_USA_Irvine/JulyAugust/" 
file_list <- list.files(path=folder, pattern="*.jpg", full.names = TRUE)
for (j in 1:30) {
myJPG <- stack(file_list[[j]])
plotRGB(myJPG)
}

As a learner, I am sure I'm going wrong somewhere and thus seek your help.

Thanks

Parag
  • 53
  • 1
  • 4

3 Answers3

14

Another solution, with the slickR package (based on the slick javascript library).

library(shiny)
library(slickR)

ui <- fluidPage(
   sidebarLayout(
      sidebarPanel(
        ####
      ),

      mainPanel(
         slickROutput("slickr", width="500px")
      )
   )
)

server <- function(input, output) {

  output$slickr <- renderSlickR({
    imgs <- list.files("D:/Photos/Foreign Trips/2014_07_08_USA_Irvine/JulyAugust/", pattern=".png", full.names = TRUE)
    slickR(imgs)
  })

}

# Run the application 
shinyApp(ui = ui, server = server)

enter image description here

Stéphane Laurent
  • 75,186
  • 15
  • 119
  • 225
  • Thanks a lot @Stephane. This looks even better with the elegant dots to navigate as well as the left and right arrows. – Parag Jul 29 '18 at 06:24
  • @SunkuVamsiTharunKumar Sorry, I don't understand your question. – Stéphane Laurent May 06 '19 at 07:29
  • @StéphaneLaurent How to get the image name of current displayed image – Sunku Vamsi Tharun Kumar May 06 '19 at 07:32
  • @SunkuVamsiTharunKumar See here: https://stackoverflow.com/questions/56001897/get-the-current-image-name-of-a-slickr-slideshow-in-shiny/56002016#56002016 – Stéphane Laurent May 06 '19 at 09:09
  • is there any way to use it with HTML tags ?? means not show pictures but show web pages with `blockquote ` tag? – Fatima Jul 24 '19 at 09:19
  • @Fatima To show a webpage, one uses `iframe`, right ? I don't see what you mean with `blockquote`. – Stéphane Laurent Jul 24 '19 at 09:26
  • @StéphaneLaurent because I need to show tweets but the iframe doesn't work with twitter URL so I have to use blockquote here is my code if you interest https://stackoverflow.com/a/56875085/10718214 – Fatima Jul 24 '19 at 09:35
  • so if I put my code start from `tagList` until end into `slickR` function I got `EROR :obj must be a character vector` is there any way to do it? I need to show 5 tweets into a slideshow – Fatima Jul 24 '19 at 09:50
  • @Fatima It's possible by using the `slick.js` library. Could you open a new question? – Stéphane Laurent Jul 24 '19 at 12:16
  • ok here is it https://stackoverflow.com/questions/57184074/web-pages-into-slideshow-use-flickr-with-html-tags – Fatima Jul 24 '19 at 13:28
5
library(shiny)

imgs <- list.files("D:/Photos/Foreign Trips/2014_07_08_USA_Irvine/JulyAugust/", pattern=".png", full.names = TRUE)

ui <- fluidPage(

  titlePanel("Slideshow"),

  sidebarLayout(
    sidebarPanel(
      actionButton("previous", "Previous"),
      actionButton("next", "Next")
    ),

    mainPanel(
      imageOutput("image")
    )
  )
)

server <- function(input, output, session) {

  index <- reactiveVal(1)

  observeEvent(input[["previous"]], {
    index(max(index()-1, 1))
  })
  observeEvent(input[["next"]], {
    index(min(index()+1, length(imgs)))
  })

  output$image <- renderImage({
    x <- imgs[index()] 
    list(src = x, alt = "alternate text")
  }, deleteFile = FALSE)
}

# Run the application 
shinyApp(ui = ui, server = server)

If you want the buttons below the image, you can do:

  sidebarLayout(
    sidebarPanel(
      # actionButton("previous", "Previous"),
      # actionButton("next", "Next")
    ),

    mainPanel(
      imageOutput("image"),
      fluidRow(
        column(1, offset=1, actionButton("previous", "Previous")),
        column(1, offset=1, actionButton("next", "Next"))
      )
    )
  )
Stéphane Laurent
  • 75,186
  • 15
  • 119
  • 225
  • Thank you very much Stephane, it worked great. Can the Previous-Next buttons be included in the main panel where the photos are getting displayed (like below the photos) instead of having them on the sidebar panel? – Parag Jul 26 '18 at 11:19
  • @Parag. Yes, see my edit. Please upvote and accept the answer if it is useful. – Stéphane Laurent Jul 26 '18 at 11:32
  • Thanks @Stephane, your edit worked. Highly appreciate the quick response. – Parag Jul 26 '18 at 11:37
  • @Stehpane, Can I clarify for one more modification? What if I want to have multiple tab panels inside the main panel? Your solution worked perfect within the main panel but when I tried to put the same inside a tab panel, it is not displaying the images. tabPanel("Photo Slide Show", imageOutput("image"), fluidRow( column(1, offset=1, actionButton("previous", "Previous")), column(1, offset=1, actionButton("next", "Next")) ). Can you please help me one last time on this (hopefully)? – Parag Jul 26 '18 at 11:50
  • @Parag Please open a new question with your code. It's more convenient. – Stéphane Laurent Jul 26 '18 at 11:52
  • I'm sorry, yes. But I got your code to work in the tabpanel - actually your edited code itself works. I made a mistake of placing it in the wrong place in the server.R. Thank you. – Parag Jul 26 '18 at 12:04
1

I wanted to do the same, but needed a static html output so couldn't use Shiny. I created a simple revealjs presentation and then included this in the flexdashboard as an iframe.

revealjs:

---
title: 
output: 
  revealjs::revealjs_presentation:
    transition: convex
    reveal_options:
      loop: true
      autoSlide: 3000
      keyboard: false
      progress: false
      shuffle: true
      embedded: true
---

```{r setup, include=FALSE}
library(tidyverse)
library(glue)
library(pander)
```

```{r echo = FALSE, results ='asis'}
files <- list.files(path="./path/to/dir", full.names = TRUE)
headers <- lapply(files,
                  function(f){glue("{data-background='{{f}}'}", 
                                   .open = "{{", 
                                   .close = "}}")
                              }) 
pandoc.header(headers, 2)
```

Then in my flexdashboard I added:

```{r}
tags$iframe(style = "height:400px; width:100%; scrolling=yes", 
            src ="./imageSlider.html")
```
vorpal
  • 268
  • 4
  • 17