Conditionally display local image in Flexdashboard

I have a shiny app that begins with a series of instructions that are conditional on the input that a user selects. I want to include both text and a local image as part of the instructions. renderUI seems to be unable to locate the local image. include_graphics displays the image as expected, but I can not make it conditional on the input that the user selects. A simple reprex is included below:

---
title: "MyApp"
runtime: shiny
output: 
  flexdashboard::flex_dashboard:
    orientation: columns
    vertical_layout: fill
---

```{r setup, include=FALSE}
library(flexdashboard)
```

Sidebar {.sidebar}
=====================================

```{r}
selectInput("input_type", 
            label = "Select an input",
            choices = list(" "=1,
                           "Input 1" = 2,
                           "Input 2" = 3))
```


MyApp
=====================================

Row {.tabset}
-----------------------------------------------------------------------

### img src

```{r}
renderUI({
  
  input_type <- input$input_type
  
  if (input_type == 1) {
    HTML('Welcome to my app! Here are some instructions about how to use it. 
A helpful image will appear when you select an input.')} 
  
  else if (input_type == 2) {
    HTML('Here are some instructions.
         <div><img src = "Posit_1.png"></div>')
  } 
  
  else if (input_type == 3) {
    HTML('Here are some other instructions. 
         <div><img src = "RStudio_2.png"></div>')
  }
  
})
```

### include_graphics

```{r}
knitr::include_graphics("Posit_1.png")
knitr::include_graphics("Rstudio_2.png")
```

Hi! So glad to find your post as I am looking for an answer too. Rather than submit to you a formalized answer, I've found this section in "Mastering Shiny". I'll be spending some time with it and may be able to provide a more detailed answer later.
Chapter 7.3 Images
--rob

Here's the code for my particular solution:

renderImage({
    if(input$mp_model_type == "xgb"){
        list(
          src = file.path("./plots/xgb_conf_matrix.jpg"),
          contentType = "image/jpeg",
          width = 275,
          height = 200
        )
    } else if (input$mp_model_type == "lr"){
        list(
          src = file.path("./plots/xgb_conf_matrix.jpg"),
          contentType = "image/jpeg",
          width = 275,
          height = 200
        )
    }
  }, deleteFile = FALSE)

Thanks so much for sharing! That works for conditionally displaying an image, but I'm trying to display an image and text. That is why I used renderUI instead of renderImage. I don't think I can conditionally display text with renderImage.

I might try creating two rows and using renderUI in the first one for the text, and renderImage in the second one for the image, and see if that works..

1 Like

I was able to add both a renderUI and renderImage within separate divs. This solved my problem, and I can now display both the instructions (text) and image conditionally.

However, I have a new problem: the image is getting cut off. Shiny/Flexdashboard doesn't seem to realize that the image is larger than the screen.

I can force it to add a scroll bar, but the scroll bar doesn't activate because it doesn't realize that the image is off the screen.

---
title: "MyApp"
runtime: shiny
output: 
  flexdashboard::flex_dashboard:
    orientation: columns
    vertical_layout: fill
---

```{r setup, include=FALSE}
library(flexdashboard)
```

Sidebar {.sidebar}
=====================================

```{r}
selectInput("input_type", 
            label = "Select an input",
            choices = list(" "=1,
                           "Input 1" = 2,
                           "Input 2" = 3))
```


MyApp
=====================================

Row {.tabset}
-----------------------------------------------------------------------

### renderUI 

<div>
```{r}
renderUI({
  
  input_type <- input$input_type
  
  if (input_type == 1) {
    HTML('Welcome to my app! Here are some instructions about how to use it. 
A helpful image will appear when you select an input.')} 
  
  else if (input_type == 2) {
    HTML('Here are some instructions.<br>
         Here are some instructions.<br>
         Here are some instructions.<br>
         Here are some instructions.<br>
         Here are some instructions.<br>
         Here are some instructions.<br>
         Here are some instructions.<br>
         Here are some instructions.<br>
         Here are some instructions.')
  } 
  
  else if (input_type == 3) {
    HTML('Here are some instructions.<br>
         Here are some instructions.<br>
         Here are some instructions.<br>
         Here are some instructions.<br>
         Here are some instructions.<br>
         Here are some instructions.<br>
         Here are some instructions.<br>
         Here are some instructions.<br>
         Here are some instructions.')
  }
  
})
```
</div>

<div>
```{r}
renderImage({
  input_type <- input$input_type
  if (input$input_type==1){
    return(list(
      src = "no_image.png",
      contentType = "image/png"
    ))
  }
  else if (input$input_type == 2) { 
    return(list(
      src = "Myimage1.png",
      contentType = "image/png",
      width=400,
      height=500
      ))
    } 
  else if (input$input_type == 3) {
    return(list(
      src = "Myimage1.png",
      filetype = "image/png"
      ))
    }
  }, deleteFile = FALSE)

```
</div>

This topic was automatically closed 54 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.