Recently, I have been struggling when trying to embed a leaflet map created with RStudio on my blog, hosted on GitHub via Jekyll (Spoiler: I succeeded ). In my case, I use the Chulapa remote theme created by myself.
Index
- The generated ToC will be an ordered list
Ready? Let’s go!
The GitHub/Jekyll part
The first step is to install the requested libraries in your GitHub page. As Jekyll basically transforms Markdown into HTML, this step is a matter of what to include and where in your own repository.
1. What to include
This part is not really hard. When looking at the source code of the Leaflet for R site, you can see this chunk:
<head>
<!--code-->
<script src="libs/jquery/jquery.min.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link href="libs/bootstrap/css/flatly.min.css" rel="stylesheet" />
<script src="libs/bootstrap/js/bootstrap.min.js"></script>
<script src="libs/bootstrap/shim/html5shiv.min.js"></script>
...
<!--more libraries-->
...
<link href="libs/rstudio_leaflet/rstudio_leaflet.css" rel="stylesheet" />
<script src="libs/leaflet-binding/leaflet.js"></script>
<!--code-->
</head>
So now we have it! The only thing to remember is that we need to load
the libraries from the **leaflet server
(https://rstudio.github.io/leaflet)**, meaning that we have to prepend
that URL to the libraries in our installation:
<script src="https://rstudio.github.io/leaflet/libs/jquery/jquery.min.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link
href="https://rstudio.github.io/leaflet/libs/bootstrap/css/flatly.min.css"
rel="stylesheet"
/>
...
<!--more libraries-->
...
<link
href="https://rstudio.github.io/leaflet/libs/rstudio_leaflet/rstudio_leaflet.css"
rel="stylesheet"
/>
<script src="https://rstudio.github.io/leaflet/libs/leaflet-binding/leaflet.js"></script>
You can have a look at my implementation in
./_includes/leaflet.html.
2. Where to include
This is a little more complicated, depending on the structure of your
Jekyll template. The code chunk should be included in the <head>
section of your page, so you would need to find where to put it. In the
case of Chulapa it is on
./_includes/custom/custom_head_before_css.html.
So now you just have to paste the code that you got in step 1 into the
<head>.
Pro tip: For a better performance of the
site, include these libraries only when you need them. In my case, I added
a custom variable in my YAML front matter for those posts with a leaflet
map, leafletmap: true. Go to step 4 for a working example.
The RStudio part
3. Creating the leaflet map
Now it’s time to create a leaflet map with RStudio. I will keep it simple for this post, so I took the first example provided in Leaflet for R - Introduction.
library(leaflet)
m <- leaflet() %>%
addTiles() %>% # Add default OpenStreetMap map tiles
addMarkers(lng=174.768, lat=-36.852, popup="The birthplace of R")
m # Print the map
It is assumed that you are creating a post with
RStudio,
so the code presented above should be embedded in an .Rmd file.
4. Set up the YAML front matter
Before knitting your .Rmd, you have to set up the YAML front
matter.
Here it is essential to set up the option always_allow_html: yes,
as well as output: github_document. As an example, this post was
created with this front matter:
---
title: Leaflet, <strong>R</strong>, Markdown, Jekyll and GitHub
subtitle: Make it work in 6 steps - a short tutorial
tags: [R, leaflet, Jekyll, html, maps]
header_img: https://dieghernan.github.io/assets/figs/20190520_imgpost.webp
leafletmap: true
always_allow_html: yes
last_modified_at: 2021-05-30
output:
md_document:
variant: gfm
preserve_yaml: true
---
We are almost there! Now “Knit” your code and get the corresponding
.md file.
The Markdown part
5. Modifying the .md file
.md fileUpdate: This is not needed any more! I still leave it here for info. You can skip to the next section.
Have a look at the .md code that you have just created. Although not
displayed in the preview, you can see in the file itself a chunk that
looks like this:
<script type="application/json" data-for="7ab57412f7b1df4d5773">
{"x":{"options":
...
"jsHooks":[]}
</script>
Actually that chunk is your leaflet map, created with RStudio. You
can’t see it now because you are previewing a markdown file in your
local PC, and the libraries installed in step 1 are installed on GitHub,
but we will solve that later.
Now you just need to paste this piece of code before that chunk:
<!--html_preserve-->
<div id="htmlwidget-7ab57412f7b1df4d5773" style="width:100%;height:216px;" class="leaflet html-widget"></div>
<script type="application/json"data-for="htmlwidget-7ab57412f7b1df4d5773">
...
Warning: Be sure that the
widget id (7ab57412f7b1df4d5773 in the example) is the same in the
<div> and in the <script> part. If not, your map would not load.
The style="width:100%; height:216px; part controls the actual size of
the leaflet widget. In this case, the map will adapt to the width of
the page with a fixed height of 216px. I put some examples of
different size options at the end of the post so you can have a look and see
which one is more suitable for your needs.
6. Publish your post
Now you just have to publish your post as usual!! If everything has been properly set, when Jekyll builds your post it will include the libraries in the header and make the magic happen, just like this:
Warning: Have you checked
the YAML front matter of your .md file? Have another look, especially
if you have followed my Pro tip.
Gallery: Size of a leaflet map
A note: For a complete understanding of this section, it is recommended to access it on multiple devices, so you can see the different behavior on different screens. Google Chrome allows you to simulate different devices (more info here).
Fixed size
With these examples, you can see how to control the absolute size of the leaflet map. The disadvantage of this method is that the size would be fixed for all the devices, so maps sized for smartphones or tablets wouldn’t look as nice in laptops, etc. and vice versa.
Example 1: 672x480px
Fixed size in pixels. By default in my machine:
leaflet(options = leafletOptions(minZoom = 1.25, maxZoom = 8)) %>%
addTiles() %>%
setMaxBounds(-200, -90, 200, 90) %>%
setView(-3.56948, 40.49181, zoom = 3)
Example 2: 200x300px
Let’s go narrow and long with html "width:200px;height:300px;":
leaflet(
options = leafletOptions(minZoom = 1.25, maxZoom = 8),
width = "200px", height = "300px"
) %>%
addTiles() %>%
setMaxBounds(-200, -90, 200, 90) %>%
setView(-3.56948, 40.49181, zoom = 3)
Responsive size
Recommended option. These maps will adapt to the width of your screen, no matter what device you are using.
Example 3: 100% width
leaflet(
options = leafletOptions(minZoom = 1.25, maxZoom = 8),
width = "100%"
) %>%
addTiles() %>%
setMaxBounds(-200, -90, 200, 90) %>%
setView(-3.56948, 40.49181, zoom = 3)