Leaflet not rendering in dynamically generated R markdown html knitr
Asked Answered
D

2

5

I've created a R markdown report where the sections and tabsets are dynamically created.

I have an issue where the Leaflet maps are not being generated in the output, but rather a blank white space. They do however render in R studio.

Here is an image showing how the output currently looks, and how it should look.

Text

Here is the code i've tried:

{r, echo = FALSE, results='asis', warning=FALSE, message=FALSE}

for (estates in filtered_list){
map_data <- x_estates %>% filter(Street_Postcode == estates)

    cat("###", estates, "{.tabset .tabset-fade .tabset-pills}", "\n")
    cat("\n\n\n")
    cat("This is where the map will go ")
    
# generate leaflet plot (doesn't even show white space if not stored in tagList)
    page <- tagList(
leaflet() %>% addTiles() %>% 
  addMarkers(map_data$Longitude, map_data$Latitude)
)

### options i've tried for getting the Leaflet map to plot correctly
   
page
print(page)
print(page[[1]])
page[[1]]
 
print(
 tagList(
     page[[1]]
    ))
 
 print(
    tagList(
     page
    ))
### end 

        cat("\n\n\n")
    

     for (major in Major$Titles) {
     
         cat("####", major, "\n")
         cat("\n\n\n") 
         
##### 
rest of code
#####

}
}


It has something to do with html rendering I presume, as static plots i've generated using ggmap work; however I want my maps to be interactive.

N.B. The maps render fine in R studio, just not in the knitr html output.

EDIT

As suggested by Susan Switzer, I have made some changes to the code. The leaflet plots now show (with interactivity too). Can alter the code to dynamically name and load the correct HTML file.

Text

    m <- leaflet() %>% addTiles() %>% 
addMarkers(map_data$Longitude, map_data$Latitude)
library(mapview)
m <- mapshot(m, url = paste0(getwd(), "/map.html"))
# m <- htmltools::includeHTML("map.html") produces an odd output where the entire document becomes a laggy leaflet map
# print(m) 

m <- htmltools::tags$iframe(title = "Map", src = "map.html")
print(m)

EDIT 2

Waldi has solved the issue when using points. However the same problem occurs when using clusters or heatmaps. e.g.

library(tidyverse)
library(leaflet)
library(leaflet.extras)
leaflet()

Minimal code to show examples with 3 sets of coordinates

long <- as.numeric(c("0.005638", "0.005648", "0.005658"))
lat <- as.numeric(c("51.62879", "51.62889", "51.62879"))
data1 <- data.frame(long, lat)


filtered_list <- 1:3
cat("## Tabs {.tabset .tabset-fade .tabset-pills}", "\n")
for (estates in filtered_list){
    cat("###", estates, "\n")
    cat("\n\n\n")
    cat("This is where the map will go ")
    
        cat("1 ")
# generate leaflet plot (doesn't even show white space if not stored in tagList)
    page <- htmltools::tagList(
         leaflet() %>%
            addTiles() %>%  # Add default OpenStreetMap map tiles
            addMarkers(lng=data1$long, lat=data1$lat, popup="The birthplace of R")
    )
    cat(as.character(page))
    
            cat("2 ")
    page <- htmltools::tagList(
         leaflet() %>%
            addTiles() %>%  # Add default OpenStreetMap map tiles
            addMarkers(lng=data1$long, lat=data1$lat, popup="The birthplace of R", clusterOptions = markerClusterOptions()) 
    )
    cat(as.character(page))
    
    
        
            cat("3 ")
    page <- htmltools::tagList(
         leaflet() %>%
            addTiles() %>%  # Add default OpenStreetMap map tiles
           addMarkers(lng=data1$long, lat=data1$lat, popup="The birthplace of R") %>% 
           addHeatmap(
    lng = data1$lat, lat = data1$long,
    blur = 20, max = 5, radius = 40
    )
    )
    cat(as.character(page))
    
    
        
            cat("4 ")
    page <- htmltools::tagList(
         leaflet() %>%
            addTiles() %>%  # Add default OpenStreetMap map tiles
           addMarkers(lng=data1$long, lat=data1$lat, popup="The birthplace of R") %>% 
           addHeatmap(
    lng = data1$lat, lat = data1$long,
    blur = 20, max = 5, radius = 40
    )
    )
    cat(as.character(page))
    
    
    }
Dreda answered 19/8, 2020 at 21:21 Comment(2)
Have you looked into the following: #31337398? I think the use of mapshot or webshot is relevant here.Afterguard
I think that will fix the issue. I've attempted it and made some progress. The leaflet maps are now displaying interactively, although all the same plot. Presumably as I am overwriting the map html. Will explore this further. i.imgur.com/8nKwuRA.png. I've updated the code above to showDreda
S
4

This is a similar problem as described here with Highcharter

Try:

---
title: "Test Leaflet Tabs"
output: html_document
---

`r knitr::opts_chunk$set(echo = FALSE, warning = FALSE, message = FALSE, cache = F)`

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

```{r,results='asis'}

filtered_list <- 1:3
cat("## Tabs {.tabset .tabset-fade .tabset-pills}", "\n")
for (estates in filtered_list){
    cat("###", estates, "\n")
    cat("\n\n\n")
    cat("This is where the map will go ")
    
# generate leaflet plot (doesn't even show white space if not stored in tagList)
    page <- htmltools::tagList(
         leaflet() %>%
            addTiles() %>%  # Add default OpenStreetMap map tiles
            addMarkers(lng=174.768, lat=-36.852, popup="The birthplace of R")
    )
    cat(as.character(page))
    }
```

enter image description here

Sloth answered 19/8, 2020 at 22:14 Comment(8)
Thanks for sharing. I did attempt that and experienced the same white box unfortunately. It renders as white space, despite "appearing" when inspecting the element: i.imgur.com/EOp5w7H.pngDreda
Did you run leaflet() once in the init chunck ? The example shared works on my system (Win 10/R 4.0.2)Sloth
Markdown copy on StackOveflow is tricky : I edited my answer because backticks disappeared on the first attempt, should be working better,Sloth
I copied your code into a new document and it worked. I then pasted in my code, part by part to ensure it still works, and now it does. I don't know what aspect of your code fixed my problem, perhaps it was indeed the leaflet() in the init chunk. Thank you so much, I spent like 6 hours yesterday scratching my head at this.Dreda
My link to Highcharter was wrong, you can read here the explainationSloth
Would you know why this fix works for points, but when introducing clusters or heatmaps it does not generate? Works fine in R studio, but doesn't when knitted. I've edited my question to include a reproducible example @Sloth Thank youDreda
@Jonathan West, I tried your second edit and don't know exactly why it doesn't work. However, I had a discussion on this with knitr team, and they warned about unexpected effects when pushing asis to its limits.Sloth
Also - if your addProviderTiles aren't showing up, just include them in the original call to leaflet in your initial chunk.Tarrah
H
1

I had a similar issue that was solved by putting the leaflet into a widget frame.

l <- leaflet() %>% 
  addTiles() %>% 
  addMarkers(map_data$Longitude, map_data$Latitude)

widgetframe::frameWidget(l, width = "100%")

This has the effect of saving html tiles for use in rendering. I'm pretty sure it just wraps the leaflet in a HMTL tag.

Hydrodynamics answered 19/8, 2020 at 22:36 Comment(2)
Just ran into this issue again and the accepted answer works for rendering from R Studio locally. But if you are displaying the Rmarkdown through Shiny Server, you will need to use the widgetframe solution.Hydrodynamics
After hours of searching for an answer, this solution works with vignettes - both leaflet and tmap. For tmap output, widgetframe::frameWidget(tmap_leaflet(map_1), width = "100%") works perfectly (just in case someone else has the same issue!)Aldine

© 2022 - 2024 — McMap. All rights reserved.