Leaflet vs. Tmap - Which Should You Use to Build Interactive Maps with R and R Shiny
So, you want to build interactive maps with R? It's harder than it seems, we know. First, you need to choose a library from an extremely competitive open-source market. Welcome to the paradox of choice. Then the real problems begin. Where do you position your map? How much zoom is enough? What about the colors? These are just a couple of questions you need to find the answer to. Today we’ll compare two libraries used to build interactive maps with R and R Shiny. These are Leaflet and Tmap - two very promising options made for different use cases. You’ll learn how to work with both, and how to embed them in R Shiny dashboards. <blockquote><strong>Interested in building interactive Google Maps? Check our <a href="https://appsilon.com/interactive-google-maps-with-r-shiny/" target="_blank" rel="noopener noreferrer">comprehensive guide to get started</a>.</strong></blockquote> Table of contents: <ul><li><a href="#leaflet">Build Interactive Maps with R and Leaflet</a></li><li><a href="#tmap">Build Interactive Maps with R And Tmap</a></li><li><a href="#shiny">Add Interactive Tmap and Leaflet Maps to R Shiny Dashboard</a></li><li><a href="#conclusion">Conclusion</a></li></ul> <hr /> <h2 id="leaflet">Build Interactive Maps with R and Leaflet</h2> <a href="https://leafletjs.com/" target="_blank" rel="noopener noreferrer">Leaflet</a> is an open-source library designed to build interactive maps with JavaScript. It was built with simplicity, performance, and usability in mind. Leaflet has full support for the R programming language, which means you don’t need to know JavaScript at all. If you’re following along, make sure to have Leaflet installed. You can install it like any other R package (<em>install.packages(“leaflet”)</em>). For the data source, we’ll use the <a href="https://www.kaggle.com/aravindram11/list-of-us-airports" target="_blank" rel="noopener noreferrer">List of US Airports dataset from Kaggle</a>. Download it and extract the CSV before proceeding. Once in RStudio, create a new R Script and paste the following code - it takes care of library imports, dataset loading, and variable setup needed for later: <script src="https://gist.github.com/darioappsilon/a8ee06662eace5826af920a3a525da8b.js"></script> Here’s how the first couple of dataset rows look like: <img class="size-full wp-image-8901" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b2670b39c9a87b7fcb6e6b_1-2.webp" alt="Image 1 - Head of the US Airports dataset" width="1636" height="298" /> Head of the US Airports dataset From here, you can proceed to build interactive maps with R and Leaflet. The first one will be rather simple - containing markers, popups, and labels for every US airport. You can use the <code>addMarkers()</code> function to add a marker based on latitude and longitude info from the dataset: <script src="https://gist.github.com/darioappsilon/a35feff87190ad711217a27f1dfdbac4.js"></script> <img class="size-full wp-image-8902" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b2670c965d463f21c3b89b_2-2.webp" alt="Image 2 - First Leaflet map" width="2138" height="1618" /> First Leaflet map Not too bad for your first Leaflet map! But there’s a lot we can improve. For example, you can use the <code>addProviderTiles()</code> function to change the default visuals of your map. We found <code>Esri.WorldStreetMap</code> to be just the right balance of color-punchy and minimalistic: <script src="https://gist.github.com/darioappsilon/63558ea1306e0880bdaef5f4e7ba30a3.js"></script> <img class="size-full wp-image-8903" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b2670d33b9c9bda3aa5f18_3-2.webp" alt="Image 3 - Changing the default visuals" width="2138" height="1618" /> Changing the default visuals Not bad, but the markers are a bit boring. As it turns out, you can use the <code>makeIcon()</code> function to replace the default marker with any PNG image - both local and online. Font Awesome’s GitHub repo contains <a href="https://raw.githubusercontent.com/Rush/Font-Awesome-SVG-PNG/master/black/png/48/plane.png" target="_blank" rel="noopener noreferrer">this plane image</a> in PNG format, and you only need the URL to use it. Don’t forget to specify the <code>icon</code> parameter inside the <code>addMarkers()</code> function, otherwise you’ll be stuck with the default one: <script src="https://gist.github.com/darioappsilon/c3d37638faa464684eb70d5de13c3ed9.js"></script> <img class="size-full wp-image-8904" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b2670e51c813d428906f77_4-2.webp" alt="Image 4 - Leaflet map with custom markers" width="2138" height="1618" /> Leaflet map with custom markers That’s much better. You might want to play with the opacity further, but this is enough for what we need today. As it turns out, that’s the map we’ll embed to an R Shiny dashboard later. But first, let’s see how you can build interactive maps with R and Tmap. <blockquote><strong>Looking for a more detailed Leaflet guide? <a href="https://appsilon.com/leaflet-geomaps/" target="_blank" rel="noopener noreferrer">Check our complete Leaflet guide built on the earthquake dataset</a>.</strong></blockquote> <h2 id="tmap">Build Interactive Maps with R and Tmap</h2> <a href="https://cran.r-project.org/web/packages/tmap/vignettes/tmap-getstarted.html" target="_blank" rel="noopener noreferrer">Tmap</a> is something else. It stands for <em>Thematic Maps</em> and provides a flexible way to visualize spatial data. It’s not the most intuitive package, which is problematic as most of the available guides are somewhat outdated and don’t cover what you would expect. However, there are numerous ways to get started with Tmap. We’ve found the most user-friendly method to be by downloading a Shapefile (.shp) first. Our dataset contains US airports, so you’ll have to find a Shapefile with US geopolitical boundaries first. We found <a href="https://github.com/datasets/geo-boundaries-us-110m" target="_blank" rel="noopener noreferrer">this one on GitHub</a>. You can clone the repo if you’re following along and extract the ZIP file. You’ll have to load three libraries and a Shapefile to get started: <script src="https://gist.github.com/darioappsilon/faebeaed0b1e30fd20e9fb96b19cfe76.js"></script> Let’s first visualize the Shapefile to see what we’re working with: <script src="https://gist.github.com/darioappsilon/3d52b899e33f2ec65a921c59e99a814b.js"></script> <img class="size-full wp-image-8905" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b2670f73fbb04260c5a714_5.webp" alt="Image 5 - Visualizing Shapefile with Tmap" width="2138" height="1618" /> Visualizing Shapefile with Tmap That’s fundamentally different from Leaflet. We don’t see a map of the entire world, but only the area of interest instead. You’ll see later how to add the above layer to an interactive map, but let’s go over the basics first. You’ll have to create an additional dataset in Tmap-approved format before you can add markers to the map. That dataset will have coordinate data explicitly declared. For simplicity’s sake, we’ll only subset our US airports dataset. You can then add and customize markers. We’ll start with simple black dots: <script src="https://gist.github.com/darioappsilon/cac217055d772c319474f026b2249b57.js"></script> <img class="size-full wp-image-8906" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b2671069991ad63e38297c_6.webp" alt="Image 6 - Adding markers to Tmap map" width="2138" height="1618" /> Adding markers to Tmap map We’re getting there. The only thing left to do is to replace black dots with the plane icons. It’s somewhat easier to do this in Tmap than it was in Leaflet. Don’t forget to specify <code>border.lwd = NA</code> inside <code>tm_symbols()</code>, as otherwise, you’ll get a border around every marker icon: <script src="https://gist.github.com/darioappsilon/2750daf944b44aa57b758845323c1848.js"></script> <img class="size-full wp-image-8907" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b01e391acc439bc2594506_7.webp" alt="Image 7 - Changing the marker icon in Tmap" width="2138" height="1618" /> Changing the marker icon in Tmap That's much better and more appropriate for our dataset. But do you know what the best part is? You can use the <code>tmap_leaflet()</code> function to add the above Tmap layer to an interactive Leaflet map: <script src="https://gist.github.com/darioappsilon/defaefaf1aa965c7728d520e63005f14.js"></script> <img class="wp-image-8908 size-full" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b2671169991ad63e382a03_8-1.webp" alt="Image 8 - Adding Tmap layer to an interactive Leaflet map - building interactive maps with r" width="2138" height="1618" /> Adding Tmap layer to an interactive Leaflet map R Shiny will automatically make this conversion for you, as you’ll see in the next section. We now have everything needed to create an interactive R Shiny dashboard from these two maps. <h2 id="shiny">Add Interactive Tmap and Leaflet Maps to R Shiny Dashboard</h2> It’s no secret that we love dashboards at Appsilon. We think they provide the best way for users to interact with data, and to pinpoint areas of interest. The one you’ll see below allows the user to specify a list of states from which the airports are displayed. Keep in mind: <ul><li><strong>App UI</strong> - Use the <code>leafletOutput()</code> and <code>tmapOutput()</code> functions to declare placeholders for our two maps.</li><li><strong>App Server</strong> - Use the <code>renderLeaflet()</code> and <code>renderTmap()</code> functions to display the maps. The data is prepared earlier as a reactive component to match the user-selected states.</li></ul> Here’s the entire code: <script src="https://gist.github.com/darioappsilon/f28824d8ffdd494db987bc9da95e957d.js"></script> <img class="wp-image-8910 size-full" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b01fa083f54e0b0d346e82_9-1.gif" alt="Image 9 - Interactive US Airports R Shiny dashboard with Tmap and Leaflet maps" width="1188" height="860" /> US Airports R Shiny dashboard with Tmap and Leaflet maps The only new thing we’ve added here is a call to the <code>tm_view()</code> function while rendering the Tmap map. It centers the map to a custom latitude, longitude, and zoom level. Everything else was discussed earlier in the article. Overall, we have a decent-looking map with less than 70 lines of code! <blockquote><strong>Learn how to use R to analyze large geolocation databases and build a <a href="https://appsilon.com/covid-19-risk-heat-maps-with-location-data-apache-arrow-markov-chain-modeling-and-r-shiny/" target="_blank" rel="noopener noreferrer">Corona Risk heat map – CoronaRank</a>.</strong></blockquote> You could take the dashboard to new heights by speeding it up and tweaking the visuals. Here’s a couple of resources to follow if you’re up for a challenge: <ul><li><a href="https://appsilon.com/ux-design-of-shiny-apps-7-steps-to-design-dashboards-people-love/" target="_blank" rel="noopener noreferrer">UX Design for Shiny Apps</a></li><li><a href="https://appsilon.com/apache-arrow-in-r-supercharge-r-shiny-dashboards/" target="_blank" rel="noopener noreferrer">Apache Arrow in R for Supercharging Shiny Dashboards</a></li></ul> <hr /> <h2 id="conclusion">Conclusion</h2> Today you’ve learned how to build interactive maps with R and R Shiny, which is no small achievement. You now know how both Leaflet and Tmap work, but we think there’s still room for improvement. Here are a couple of challenges you can do next: <ul><li>Change the coloring on the Tmap map to match what we had with Leaflet</li><li>Add a dark theme to the Leaflet map</li><li>Color individual states on the Tmap map based on the number of airports they have</li></ul> Reference the official documentation for Leaflet and Tmap if you decide to work on these challenges. Feel free to share results with us on Twitter - <a href="https://twitter.com/appsilon" target="_blank" rel="noopener noreferrer">@appsilon</a>. We’d love to see what you came up with. If you’re looking for a faster way to showcase your map online, check out our <a href="https://templates.appsilon.com/" target="_blank" rel="noopener noreferrer">Shiny Dashboard Templates</a>. They’re free to use and a great launching point for your project.