<p><div><div><div><div data-width="100" data-show-faces="false" data-send="true" data-layout="button_count" data-height="21" data-href="https://www.r-bloggers.com/mapmate-0-1-0/"></div></div><div><a data-url="https://www.r-bloggers.com/mapmate-0-1-0/" data-counturl="https://www.r-bloggers.com/mapmate-0-1-0/" data-count="horizontal" data-text="mapmate 0.1.0" class="twitter-share-button" data-via="rbloggers" href="https://twitter.com/share"></a></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="https://blog.snap.uaf.edu/2016/11/01/mapmate-0-1-0/"> rbloggers – SNAP Tech</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<p><a target="_blank" rel="nofollow" href="https://github.com/leonawicz/mapmate">mapmate</a> has now been updating from version 0.0.2 to 0.1.0 on Github. The biggest addition is a number of plotting options for making different kinds of maps. The new tutorial content below provides a number of code examples for making a variety of maps and also highlights current limitations associated with certain map types and settings.</p>
<p>Since the code snippets below generate a lot of different plots, the plots are not contained directly in this blog post. See the <a target="_blank" rel="nofollow" href="https://leonawicz.github.io/mapmate/usage_and_limitations.html">full tutorial page</a> to see everything. It will also be easier and cleaner to review the examples from there. There is also the accompanying <a target="_blank" rel="nofollow" href="https://leonawicz.github.io/mapmate/mapmate.html">introductory vignette</a>. All can be accessed from the <a target="_blank" rel="nofollow" href="https://leonawicz.github.io/mapmate/">mapmate Github pages</a>.</p>
<p><a target="_blank" rel="nofollow" href="https://i1.wp.com/uasnap.files.wordpress.com/2016/10/bkgd.jpg?ssl=1"><img sizes="(max-width: 300px) 100vw, 300px" alt="bkgd" class="wp-image-1387" src="https://i1.wp.com/uasnap.files.wordpress.com/2016/10/bkgd.jpg?resize=300%2C159&ssl=1" data-recalc-dims="1"></a></p>
<p><span></span></p>
<p>To install the package:</p>
<pre>
devtools::install_github(&quot;leonawicz/mapmate&quot;)
</pre>
<h1>Introduction and motivation</h1>
<p>The <code>mapmate</code> package is used for map- and globe-based data animation pre-production. Specifically, <code>mapmate</code> functions are used to generate and save to disk a series of map graphics that make up a still image sequence,<br>
which can then be used in video editing and rendering software of the user’s choice. This package does not make simple animations directly within R, which can be done with packages like <code>animation</code>. <code>mapmate</code> is more specific to maps, hence the name, and particularly suited to 3D globe plots of the Earth.</p>
<p>The motivation for the package is to assist with heavy data processing and image production for large, complex data animation videos that can require a significant amount of computing resources to create. It is best suited to use on a Linux server with a significant number of CPU cores and a significant amount of RAM. It is all about video pre-production. Still image sequences created by R are meant to be rendered into video subsequently by dedicated video editing software. It makes the most sense to leverage the power of both programs for what they are best designed for: R for data analysis and plotting and something else for high quality video rendering.</p>
<p>As mentioned, there are other solutions for producing animations completely from R with only implicit external software dependencies (e.g., using the <code>rgl</code> package or relying on <code>ImageMagick convert</code>). The only restriction is that you have to want to create an animation that is small and simple enough for other solutions to remain realistic options. At some point the size of data or the images or the total number of frame or some other limitation may creep in and stop you if your animation is just simply too big or complex. At that point, this package has the value of being dedicated to generating still image sequences to pass to another program. If you ever make videos which require the use of video editing software, then you will know at what point it makes sense to just make still image sequences that you can drop on your timeline to finish your video project rather than trying to force R to do the entire job itself.</p>
<p>Nevertheless, while the strength of R for pre-production lies in its data analysis, processing and graphing capabilities, there are some limitations to how well <code>save_map</code> in the <code>mapmate</code> package will draw certain types of maps of certain types of data sets. The biggest limitation is in attempting to draw filled in polygons on a map using an orthographic projection; the 3D Earth globe view.</p>
<p>Below is a series of usage examples of <code>save_map</code> applied to example data included in the package. The examples show how to make different maps based on the different arguments that can be passed to <code>save_map</code>. They also show how some of the options for map types included <code>save_map</code> are primarily included to reveal their current limitations in drawing maps. Points, paths and tiles tend to work well, as do contour lines for the most part, but polygons often display serious clipping issues.</p>
<p>This package depends heavily on <code>ggplot2</code> for plotting. While it is easy enough to write a function that returns an ordered set of lon/lat coordinates defining the circle that represents the edge the hemisphere in view for orthographically projected data, I have not yet found a way in this context to use that circle to essentially reclip the polygons. If I could do so, then I could potentially apply the reclipping inside <code>save_map</code> when <code>ortho=TRUE</code> prior to the reprojection done by <code>ggplot2::coord_map</code>. But not so easily, if the data are not actually projected to the orthographic projection until passed to and as done so by <code>coord_map</code>. The reliance on <code>coord_map</code> could cripple my ability to insert a reclipping step where I need to, but I haven’t delved into it yet since my main use of the package is not for polygons.</p>
<p>Lastly, since these examples are simply intended to display what kind of map outputs are made given the various arguments that can be passed to <code>save_map</code>, the plot or image frame number/ID value never goes beyond <code>1</code> and <code>save_map</code> is not called iteratively. For code related to typical map sequence generation see the introductory vignette for examples: <code>browseVignettes(package=&quot;mapmate&quot;)</code> or <a target="_blank" rel="nofollow" href="https://leonawicz.github.io/mapmate/mapmate.html">view it here</a>.</p>
<h1>Setup</h1>
<p>First some setup using the package data:</p>
<pre>
library(mapmate)
library(dplyr)
library(RColorBrewer)
pal &lt;- rev(brewer.pal(11, &quot;RdYlBu&quot;))

data(annualtemps)
data(borders)
data(bathymetry)

id &lt;- &quot;frameID&quot;
temps &lt;- mutate(annualtemps, frameID = Year - min(Year) + 1) %>% filter(frameID == 
    1)  # subset to first frame
brdrs &lt;- mutate(borders, frameID = 1)
bath &lt;- mutate(bathymetry, frameID = 1)
</pre>
<p>Next for the plots. Note that the aptly named <code>save_map</code> is not typically used for returning plot objects but rather for saving them to disk, hence why every call to <code>save_map</code> in this set of examples must explicitly include the non-default <code>save.plot</code> and <code>return.plot</code> arguments.</p>
<h1>Flat world maps vs 3D Earth</h1>
<p>Use <code>ortho=TRUE</code> (default) or <code>ortho=FALSE</code>.</p>
<pre>
save_map(temps, id = id, ortho = FALSE, col = &quot;dodgerblue&quot;, type = &quot;points&quot;, 
    save.plot = FALSE, return.plot = TRUE)
save_map(temps, id = id, col = &quot;#FF4500&quot;, type = &quot;points&quot;, save.plot = FALSE, 
    return.plot = TRUE)
</pre>
<h1>Simple points</h1>
<p>The previous examples use point data. To confirm this works with points everywhere, depending on the resolution of the source data, here is another example using the bathymetry surface with <code>type=&quot;points&quot;</code>.</p>
<pre>
save_map(bath, id = id, type = &quot;points&quot;, save.plot = FALSE, return.plot = TRUE)
</pre>
<h1>Spatial/polygon boundary lines</h1>
<p><code>type=&quot;maplines&quot;</code> relies on <code>ggplot2::geom_path</code> internally, which is why it is suited to drawing ordered polygon border lines and why the original <code>borders</code> data frame contains the necessary additional variables. While the prepared data frames used in this set of examples are provided by the package, typically you would generate these yourself from your data which were originally in another form such as <code>SpatialPolygonsDataFrame</code> or <code>RasterLayer</code> objects. A common way to do this is by using <code>ggplot2::fortify</code> or, alternatively, duplicated functionality in the <code>broom</code> package. See those for examples or documentation.</p>
<pre>
save_map(brdrs, id = id, type = &quot;maplines&quot;, save.plot = FALSE, return.plot = TRUE)
</pre>
<p>While we’re here, let’s also change the view using <code>lon</code>, <code>lat</code>, and <code>rotation.axis</code>.</p>
<pre>
save_map(brdrs, id = id, lon = -70, lat = 40, rotation.axis = 0, type = &quot;maplines&quot;, 
    save.plot = FALSE, return.plot = TRUE)
</pre>
<h1>Rasterized tiles</h1>
<p>In the previous examples there was no need to provide a third variable, a data variable. The plots are based on spatial locations only, whether points or paths. For gridded data, a <code>z</code> variable is needed and is specified with the <code>z.name</code> argument.</p>
<pre>
save_map(bath, z.name = &quot;z&quot;, id = id, col = pal, type = &quot;maptiles&quot;, save.plot = FALSE, 
    return.plot = TRUE)
</pre>
<h1>Density maps and contour lines</h1>
<p><code>type=&quot;density&quot;</code> combines both 2D density and 3D contour mapping under a single heading for convenience and based on the default map appearance, but it is important to remember the distinction. The previous example using <code>type=&quot;maptiles&quot;</code> is actually a special case and matches the plot output associated with the default arguments that are relevant to <code>type=&quot;density&quot;</code>.</p>
<h2>Filled contour-style density using tiles</h2>
<p>Default arguments include <code>contour=&quot;none&quot;</code> and <code>density.geom=&quot;tile&quot;</code>.</p>
<pre>
save_map(bath, z.name = &quot;z&quot;, id = id, col = pal, type = &quot;density&quot;, save.plot = FALSE, 
    return.plot = TRUE)
</pre>
<p>Explicit contour lines can also be overlaid with the base map type.</p>
<pre>
save_map(bath, z.name = &quot;z&quot;, id = id, col = pal, type = &quot;density&quot;, contour = &quot;overlay&quot;, 
    save.plot = FALSE, return.plot = TRUE)
</pre>
<p>Contour lines can also be drawn without including the base layer indicated by <code>type</code>.</p>
<pre>
save_map(bath, z.name = &quot;z&quot;, id = id, col = pal, type = &quot;density&quot;, contour = &quot;only&quot;, 
    save.plot = FALSE, return.plot = TRUE)
</pre>
<h3>Contour lines with points</h3>
<p>As a brief aside, these options also work for <code>type=&quot;points&quot;</code>. Remember that these contour lines are based on the spatial density of lon/lat coordinates, unlike the previous contour lines examples that make use of the data variable.</p>
<pre>
save_map(temps, id = id, col = &quot;red&quot;, type = &quot;points&quot;, contour = &quot;overlay&quot;, 
    save.plot = FALSE, return.plot = TRUE)
save_map(temps, id = id, col = &quot;blue&quot;, type = &quot;points&quot;, contour = &quot;only&quot;, save.plot = FALSE, 
    return.plot = TRUE)
</pre>
<p>For <code>type=&quot;points&quot;</code>, the color <code>col</code> applies to both points and contour lines, but for <code>type=&quot;density&quot;</code> <code>col</code> applies to the density map. Contour line overlays will remain as black lines. The exception is when <code>contour=&quot;only&quot;</code>, in which case <code>col</code> may still be a vector defining a color palette that will be applied to the contour lines in place of the underlying filled density map.</p>
<h2>Density maps of locations (no data variable)</h2>
<p>True density maps based on lon/lat locations rather than filled contours based on three variables can also be plotted by excluding <code>z.name</code>. The first call below includes <code>z.name=&quot;z&quot;</code> and the second does not. As expected, these are completely different maps because they use fundamentally different data in different ways.</p>
<pre>
save_map(temps, z.name = &quot;z&quot;, id = id, col = pal, type = &quot;density&quot;, contour = &quot;overlay&quot;, 
    save.plot = FALSE, return.plot = TRUE)
save_map(temps, id = id, col = pal, type = &quot;density&quot;, contour = &quot;overlay&quot;, save.plot = FALSE, 
    return.plot = TRUE)
</pre>
<p>Of course, this would not be interesting to do when the data frame contains gridded data at all lon/lat locations on the world grid like in <code>bathymetry</code>.</p>
<pre>
save_map(bath, id = id, lon = -70, lat = 50, col = pal, type = &quot;density&quot;, contour = &quot;overlay&quot;, 
    save.plot = FALSE, return.plot = TRUE)
</pre>
<h2>Tiles vs. polygons</h2>
<p>Relying internally on <code>ggplot2::geom_polygon</code> inside <code>save_map</code> can be much faster than <code>ggplot::geom_tile</code> to process the data and make maps. This is an important consideration for generating long sequences of many high-resolution maps. However, the trade off is that polygons may be drawn very poorly with much clipping, the degree of the problem depending on the given data. Of course, if tiles are drawn at an extremely coarse resolution based on the input data, they still won’t look good, and also won’t take as long to draw. It is what you decide to make of it with the data you choose to map. The below examples compare the use of tiles to polygons.</p>
<pre>
save_map(temps, z.name = &quot;z&quot;, id = id, col = pal, type = &quot;density&quot;, contour = &quot;overlay&quot;, 
    density.geom = &quot;tile&quot;, save.plot = FALSE, return.plot = TRUE)
save_map(temps, z.name = &quot;z&quot;, id = id, col = pal, type = &quot;density&quot;, contour = &quot;overlay&quot;, 
    density.geom = &quot;polygon&quot;, save.plot = FALSE, return.plot = TRUE)
save_map(bath, z.name = &quot;z&quot;, id = id, col = pal, type = &quot;density&quot;, contour = &quot;overlay&quot;, 
    density.geom = &quot;tile&quot;, save.plot = FALSE, return.plot = TRUE)
save_map(bath, z.name = &quot;z&quot;, id = id, col = pal, type = &quot;density&quot;, contour = &quot;overlay&quot;, 
    density.geom = &quot;polygon&quot;, save.plot = FALSE, return.plot = TRUE)
</pre>
<p>Tiles may also interpolate where possible, but not extrapolate, which may not be desired behavior for a map; e.g., when drawing the continents and interpolating between them but still excluding the poles. It can lead to confusion about what is the underlying data. Yet polygons may still perform much worse, even in flat maps, as shown below.</p>
<pre>
save_map(temps, id = id, col = pal, type = &quot;density&quot;, contour = &quot;overlay&quot;, density.geom = &quot;tile&quot;, 
    save.plot = FALSE, return.plot = TRUE)
save_map(temps, id = id, col = pal, type = &quot;density&quot;, contour = &quot;overlay&quot;, density.geom = &quot;polygon&quot;, 
    save.plot = FALSE, return.plot = TRUE)
save_map(temps, id = id, col = pal, type = &quot;density&quot;, ortho = FALSE, contour = &quot;overlay&quot;, 
    density.geom = &quot;tile&quot;, save.plot = FALSE, return.plot = TRUE)
save_map(temps, id = id, col = pal, type = &quot;density&quot;, ortho = FALSE, contour = &quot;overlay&quot;, 
    density.geom = &quot;polygon&quot;, save.plot = FALSE, return.plot = TRUE)
</pre>
<h2>An example from scratch</h2>
<p>This is also apparent when using the simpler options <code>type=&quot;polygons&quot;</code> and <code>type=&quot;maptiles&quot;</code>. The former relies on a <code>SpatialPolygonsDataFrame</code> object as the data source and the later on a <code>RasterLayer</code>. Here examples of each are compared and they are prepped from scratch using the appropriate class objects. Remember that these two map type options are essentially special cases of the density type option.</p>
<pre>
# polygons
library(rworldmap)
library(rworldxtra)  # required for 'high' resolution map
library(maptools)  # required for fortify to work
# also recommend installing rgeos

spdf &lt;- joinCountryData2Map(countryExData, mapResolution = &quot;high&quot;)
spdf@data$id &lt;- rownames(spdf@data)
bio &lt;- ggplot2::fortify(spdf, region = &quot;id&quot;) %>% left_join(subset(spdf@data, 
    select = c(id, BIODIVERSITY)), by = &quot;id&quot;) %>% mutate(frameID = 1) %>% rename(lon = long)

# raster layer
library(raster)
proj4 &lt;- &quot;+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +to wgs84=0,0,0&quot;
z &lt;- &quot;BIODIVERSITY&quot;
# 1-degree resolution, still somewhat coarse
r &lt;- raster(extent(-180, 180, -90, 90), nrow = 180, ncol = 360, proj4)
bio2 &lt;- rasterize(spdf, r, field = z) %>% rasterToPoints %>% tbl_df() %>% setNames(c(&quot;lon&quot;, 
    &quot;lat&quot;, z)) %>% mutate(frameID = 1)

clrs &lt;- c(&quot;royalblue&quot;, &quot;purple&quot;, &quot;orange&quot;, &quot;yellow&quot;)
save_map(bio, z.name = z, id = id, lon = -10, lat = 20, col = pal, type = &quot;polygons&quot;, 
    save.plot = FALSE, return.plot = TRUE)
save_map(bio2, z.name = z, id = id, lon = -10, lat = 20, col = pal, type = &quot;maptiles&quot;, 
    save.plot = FALSE, return.plot = TRUE)
</pre>
<p>In conclusion, there are a variety of methods available to draw different types of data on the globe from any arbitrary perspective. Flat maps are also an option but this is not as interesting so it is not focused on. The primary uses of <code>save_map</code> among what is shown here are for plotting points, polygon borders and tiles. The rest are interesting options and can work well enough for specific use cases but are included here mainly to highlight their current limitations.</p>
<p>The one option not covered here (I will add this in a future update) is the <code>type=&quot;network&quot;</code> option, which is used for plotting a time series of maps/globes showing moving great circle arcs. This is my personal favorite use case, but it is also the most complex so I am yet to fold code for that into this package and incorporate great circle arc network examples into the various help documentation, vignettes and tutorials. Something more to look forward to.</p>
<h1>mapmate 0.1.0 (Release date: 2016-11-01)</h1>
<ul>
<li>Add <code>type</code> argument options to <code>save_map</code> for points, contour lines, filled contour maps, density/intensity maps</li>
<li>Added ability to choose between tile- and polygon-based plotting with <code>type=&quot;density&quot;</code>.</li>
<li>Contour lines can be added on top of density maps, underneath points, or plotted alone as a substitute for either <code>type=&quot;points&quot;</code> or <code>type=&quot;density&quot;</code> maps.</li>
<li>Added a new web page document that provides plenty of examples with visuals on the usage of different <code>save_map</code> arguments<br>
and more thorough coverage of the limitations associated with using polygons.</li>
<li>Remade package website/Github pages to include home page, introductory vignette page, and page showcasing visual examples and current mapping limitations.</li>
<li>Added orthographic projection example Shiny app into package website page.</li>
</ul>
<p><img alt="" src="https://i1.wp.com/pixel.wp.com/b.gif?resize=1%2C1&ssl=1" border="0" data-recalc-dims="1"></p>
<p><div><div><div><div data-width="55" data-show-faces="false" data-send="true" data-layout="box_count" data-height="62" data-href="https://www.r-bloggers.com/mapmate-0-1-0/"></div></div><div><a data-url="https://www.r-bloggers.com/mapmate-0-1-0/" data-counturl="https://www.r-bloggers.com/mapmate-0-1-0/" data-count="vertical" data-text="mapmate 0.1.0" class="twitter-share-button" data-via="rbloggers" href="https://twitter.com/share"></a></div><div></div></div><div></div></div>
<div>
<div>To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://blog.snap.uaf.edu/2016/11/01/mapmate-0-1-0/"> rbloggers – SNAP Tech</a></strong>.</div>
<hr>
<a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers.com</a> offers <strong><a rel="nofollow" href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" rel="nofollow" href="https://www.r-project.org/">R</a> news and <a title="R tutorials" rel="nofollow" href="https://www.r-bloggers.com/?s=tutorial">tutorials</a> on topics such as: <a title="Data science" rel="nofollow" href="https://www.r-bloggers.com/?s=data%20science">Data science</a>, <a title="Big Data" rel="nofollow" href="https://www.r-bloggers.com/?s=Big%20Data">Big Data, <a title="R jobs" rel="nofollow" href="https://www.r-users.com/">R jobs</a>, visualization (<a title="ggplot and ggplot2 tutorials" rel="nofollow" href="https://www.r-bloggers.com/?s=ggplot2">ggplot2</a>, <a title="Boxplots using lattice and ggplot2 tutorials" rel="nofollow" href="https://www.r-bloggers.com/?s=boxplot">Boxplots</a>, <a title="Maps and gis" rel="nofollow" href="https://www.r-bloggers.com/?s=map">maps</a>, <a title="Animation in R" rel="nofollow" href="https://www.r-bloggers.com/?s=animation">animation</a>), programming (<a title="RStudio IDE for R" rel="nofollow" href="https://www.r-bloggers.com/?s=RStudio">RStudio</a>, <a title="Sweave and literate programming" rel="nofollow" href="https://www.r-bloggers.com/?s=sweave">Sweave</a>, <a title="LaTeX in R" rel="nofollow" href="https://www.r-bloggers.com/?s=LaTeX">LaTeX</a>, <a title="SQL and databases" rel="nofollow" href="https://www.r-bloggers.com/?s=SQL">SQL</a>, <a title="Eclipse IDE for R" rel="nofollow" href="https://www.r-bloggers.com/?s=eclipse">Eclipse</a>, <a title="git and github, Version Control System" rel="nofollow" href="https://www.r-bloggers.com/?s=git">git</a>, <a title="Large data in R using Hadoop" rel="nofollow" href="https://www.r-bloggers.com/?s=hadoop">hadoop</a>, <a title="Web Scraping of google, facebook, yahoo, twitter and more using R" rel="nofollow" href="https://www.r-bloggers.com/?s=Web+Scraping">Web Scraping</a>) statistics (<a title="Regressions and ANOVA analysis tutorials" rel="nofollow" href="https://www.r-bloggers.com/?s=regression">regression</a>, <a title="principal component analysis tutorial" rel="nofollow" href="https://www.r-bloggers.com/?s=PCA">PCA</a>, <a title="Time series" rel="nofollow" href="https://www.r-bloggers.com/?s=time+series">time series</a>, <a title="finance trading" rel="nofollow" href="https://www.r-bloggers.com/?s=trading">trading</a>) and more...
<img height="1" alt="" width="1" src="http://feeds.feedburner.com/~r/RBloggers/~4/0yKgXdgQojU"></a></div>