4

I spent a fair amount of time trying to solve that issue. Of course I did my homework before sharing my issue here.

In particular I have unsuccessfully consulted :

  1. local image in shiny app without img(src())?
  2. Shiny can not display Image locally
  3. adding local image with html to a Shiny app
  4. R Shiny img() on UI side does not render the image
  5. Display images from web in shiny R
  6. Image failing to display in R shiny
  7. Embedding Image in Shiny App
  8. How to place an image in an R Shiny title

So I did create a 'www' folder at the root of the RStudio project file where I put some pictures.

These pictures are used in the titlePanel but also by the main htmlwidget the application calls.

It is crucial for me to have these pictures stored locally because the application may be running in a secured environment without any access to the Internet.

I tried a relative path to these pictures and an absolute path: no picture was displayed.

Then I noticed some kind of inconsistency: I experience this issue only when I run the application through the regular command in RStudio, "Run Selected Line(s)". On the other hand, when I run the application through the dedicated command "Run App" (in the top right corner in RStudio, green arrow), I don't have this issue anymore, the pictures display nicely (but the input data are somehow inspected and it takes a lot of time before the application is launched).

Initially I thought that displaying local images would be much easier than with remote images stored on the Internet but it seems it is rather the other way around.

Hence my questions:

  1. Do you know why we can observe this difference (which is an inconsistency to me)?
  2. And do you know how I could still continue to use the regular execution command ("Run Selected Line(s)")?

Best regards,

Olivier

Olivier7121
  • 151
  • 1
  • 11

3 Answers3

3

For me the following also works when running the app via Run Selected Line(s) in RStudio:

library(shiny)

# create some local images
if(!dir.exists("myimages")){
  dir.create("myimages")
}

myPlotPaths <- paste0("myimages/myplot", seq_len(3), ".png")

for (myPlot in myPlotPaths) {
  png(file = myPlot, bg = "transparent")
  plot(runif(10))
  dev.off() 
}

myImgResources <- paste0("imgResources/myplot", seq_len(3), ".png")

# Add directory of static resources to Shiny's web server
addResourcePath(prefix = "imgResources", directoryPath = "myimages")

ui <- fluidPage(
  tags$img(src = myImgResources[1], width = "400px", height = "400px"),
  tags$img(src = myImgResources[2], width = "400px", height = "400px"),
  tags$img(src = myImgResources[3], width = "400px", height = "400px")
)

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

shinyApp(ui, server)
ismirsehregal
  • 30,045
  • 5
  • 31
  • 78
  • Many thanks, @ismirsehregal (nice pseudo BTW :D), for your answer with the reproducible example! Your code also works fine on my machine when I turn my Internet connection off. But I don't understand why you use `addResourcePath`? So in your code I commented this line: `addResourcePath(prefix = "imgResources", directoryPath = "myimages")` and replaced `tags$img(src = myImgResources[1], width = "400px", height = "400px")` (and other similar lines) with `tags$img(src = myPlotPaths[1], width = "400px", height = "400px")` and it doesn't work anymore without Internet... – Olivier7121 Sep 11 '20 at 11:11
  • So if I understand correctly (I looked at the function `addResourcePath` documentation but thought it was intended only for packages) this function `addResourcePath` is necessary to make the bridge between the true local paths and the Shiny server paths? BTW, I also renamed your local folder 'myimages' to 'www' and ran the modified code as described in the previous message but it didn't work either. Although (from the function documentation): "Static files under the www/ directory are automatically made available under a request path that begins with /." – Olivier7121 Sep 11 '20 at 11:17
  • 1
    Exactly, using `addResourcePath` you can "introduce" local resources to the webserver. Normally for the www folder this is done automatically. – ismirsehregal Sep 11 '20 at 11:28
  • 1
    Regarding my first comment here, of course having the Internet connection off or on doesn't matter... – Olivier7121 Sep 11 '20 at 11:29
  • Yep - so can you build on this example? – ismirsehregal Sep 11 '20 at 11:32
  • OK, thank you, @ismirsehregal. Indeed, after the plots were created in a `www` subfolder, I created `myNewPlotPaths <- paste0("/myplot", seq_len(3), ".png")` (with or without '/' before 'myplot', it seems to have no effect) and ran your code by replacing with `tags$img(src = myNewPlotPaths[1], width = "400px", height = "400px")` but no plot was displayed. Strange. – Olivier7121 Sep 11 '20 at 11:35
  • Seems that the `www` folder isn't made available to the webserver when using `Run Selected Line(s)` (if not done expicitly via `addResourcePath`). You could ask about this here: https://community.rstudio.com/ and keep us updated. – ismirsehregal Sep 11 '20 at 11:53
  • Sorry that it took me so long. Yes, thanks again, @ismirsehregal, it works fine now on my one code! I just added these 2 lines: `addResourcePath(prefix = "Flags", directoryPath = file.path(".", "Input", "Flags"))` `Address2Flags <- ifelse(has_internet(), "http://lipis.github.io/flag-icon-css/flags/1x1/", "Flags/")` – Olivier7121 Sep 11 '20 at 11:58
  • 1
    Yes, good idea, thanks. I just created [a new topic](https://community.rstudio.com/t/www-folder-unavailable-to-the-webserver-when-using-run-selected-line-s-in-rstudio/80177) on RStudio website. Yes, answer accepted :) – Olivier7121 Sep 11 '20 at 12:10
0

Managing directories can be tricky.

You could use the here package to make things much easier to handle directories in R projects, see Ode to the here package.

After opening the project, images in www can then easily be accessed by:

here::here('www/myimage.jpg')

This will also work for sourcing an app or a script.

Waldi
  • 39,242
  • 6
  • 30
  • 78
  • Thanks, @Waldi, for your answer and suggestion. I think the package `here` is useless, especially because I use RStudio project files (as I mentioned in my question, and as you suggested too), so I am already working with relative paths within the application. But I think the issue is somewhere else: in my opinion results should not depend on the way you launch the application - 'regular' through the 'Run Selected Line(s)' command or through the dedicated command 'Run App'. – Olivier7121 Sep 11 '20 at 07:20
  • @Olivier7121, you're right, you already mention that you use projects! I find `here` especially useful in these situations in a project when you switch from interactive session (run a few lines) to source / run script mode. Did you give it a try? So useful that I don't even think whether it's really useful or not..., the few extra characters make me confident it will work as expected. But it might really be useless in some situations. – Waldi Sep 11 '20 at 09:58
  • Yes, I did try `here` and that's why I found it useless. Let's say it didn't find a proper use for this package yet... The few extra characters I use are simply `file.path(".", "SomeSubFolder")`. – Olivier7121 Sep 11 '20 at 11:04
  • Here is my complete reasoning w.r.t. `here`: If the root R project file (.Rproj) is opened with RStudio or if any R script located in the folder or subfolder of this R project file is opened from RStudio via this R project file, then the package `here` is useless as the current working directory (`getwd()`) is set to the R project file directory already and the base R function `file.path` takes care of constructing platform-independent (esp. w.r.t. path separator) paths. – Olivier7121 Sep 12 '20 at 08:15
  • If the R data file (.RData) is opened with the default R GUI (should be the case by default, the association is made by default) or if any R script located in the folder or subfolder of this R data file is opened from the default R GUI via this R data file then the package `here` is also useless as the current working directory (`getwd()`) is set to the R data file directory already (but it might be platform-dependent - esp. might not work on Mac) and the base R function `file.path` takes care of constructing platform-independent (esp. w.r.t. path separator) paths. – Olivier7121 Sep 12 '20 at 08:15
  • When a fresh R session is started (be it from the default R GUI or RStudio) from R's default (i.e. installation) location it may / will simply not work. The only occasion where `here` is useful is when an R script is opened with the default R GUI or RStudio *with a right click on this R script* (i.e. Open with, etc.). This is of too limited use to me: I decided to use only the base R function `file.path`. – Olivier7121 Sep 12 '20 at 08:16
  • For a somewhat polemical discussion about relative paths in R, you can read [this (long) thread](https://stat.ethz.ch/pipermail/r-help/2018-October/456664.html). – Olivier7121 Sep 12 '20 at 08:21
0

I don't have a specific answer, but Hadley has showed an example of how to display images from your stored locally under the 'Graphics' Chapter in 'Mastering shiny' book. The book is under development and it should be released soon, I will paste the link for that chapter:

Graphics chapter

The example is under images section.

HTH