With so many tools and software options available to create maps and analyze spatial data, it’s really not surprising that the hurdles required to learn how to use them can seem insurmountable. My first job out of college involved learning how to use ESRI’s ArcGIS one painful hour after another. Eventually it became pretty straightforward to do many tasks, including making quality maps. It’s a skill that required a lot of practice making awful maps, and having other people provide feedback (e.g., constructively telling you your maps suck). This process taught me a lot about not just how to use a spatial mapping software, but how to make something graphically pleasing, the importance of colors, fonts, font-sizes, etc. How a nice map can have a much greater influence on a reader and it can provide a much better way to convey data if done correctly.
Good thing this blog isn’t going to really be about any of that. I’m writing this blog because I was recently quite frustrated with the awkward and we’ll call it quasi-backwards compatability of non-open-source spatial software (for example, ArcGIS…not that I’m pointing fingers). I wanted to make a simple map. I started making it on one computer at work, and then when trying to open on a different computer, found I was unable to access that map because the versions were different. Sure, I should have followed a number of steps that would have allowed me to save to a previous version, which then could be read by both computers in question. Reality is, that didn’t happen.
Open Source Spatial Tools
Admittedly, I use ArcGIS because I have access to it, and the license fees are covered by my employers, and I’ve used it for years. It’s comfortable. I know where to find things, how to make a nice map, and can usually do so in a fairly short amount of time. I know there are some great alternatives out there, namely R (the focus of this blog), and QGIS. I should and could use these options, but have just put it off because I didn’t want to spend the time re-learning all the little tricks and tweaks I can do in ArcGIS. But this last experience pretty much lit a fire under me to see exactly how long it would take me to make a nice map (for a manuscript) in R.
So how long did it take? Total hours was probably somewhere around 3-4 all said and done. I could have made the same map in about 20 minutes in ArcGIS. But now I have code, which I’m posting here so
I can look it up again when I forget, and
hopefully someone can save themselves some time and use this!
R Spatial Packages
There are loads of spatial mapping/plotting packages in R, and I’ve used a number of them. But I wanted to stick with pipelines I was mostly familiar with, so I mainly focus on using ggplot2/tidyverse options here. These are the packages I ended up using, but there are certainly other options.
Get Data & Make it Spatial
This is a subset of some data on study sites but it will suffice for our example. It has data in UTMs and as Lat/Longs, and columns with XY and lat/lon headers. Let’s walk through reading this in, making it spatial, and reprojecting (or adding a projection). Projections are honestly the hardest part when dealing with spatial data, but once sorted it’s pretty straightforward to make some maps! Just try to figure out what your spatial data is projected in and go from there. You can always convert between formats. Importantly, make sure you are always using X/UTM_Easting/longitude and Y/UTM_Northing/latitude columns and you know what datum you are using (i.,NAD83, WGS84, etc).
Project and Re-project!
Importantly you’ll need to know what your datum is if you want to convert or reproject to a standard that most mapping packages use (typically WGS84). To do so requires using something called CRS or the Coordinate Reference System which helps assign a datum, projection, and ellipsoid (earth curvature). Sometimes when you bring data (as in the case above where we read a csv in) in it doesn’t have this information, and you need to assign a projection/datum. When reading in shapefiles, typically they will have this data already associated with them. Either way, we can check, and it’s easy to change as needed. These CRS can be called using a unique code, called EPSG. For more than you could ever want, see this page or this one for lists of codes, etc.
Ok! So we’ve pulled in a list of sites, could have come from field work, a GPS device, whatever. We converted from UTM to lat/lon & we projected this dataset into WGS84 which is fairly universal (and easily plotted in things like googlemaps, leaflet, Google Earth, etc.).
Let’s get a shapefile and read it in as well. For this I used a shapefile I created with major rivers draining from the Sierras and the San Joaquin/Sacramento Valley. I’m using the rgdal package here, but there are many that will read/work with shapefiles.
Making a Basic Map!
Now that we spent some time figuring out our CRS and loading up some files, we can make a basic map using the maps and mapsdata packages. I’m using the viridis package to pull some nice colors for use in the map. Not necessary, but just throwing it out there. The basic plotting package is nice, and allows you to specify location and region (world wide or within US). I’ve limited to a specific lat and long range using the xlim and ylim functions.
Ok, so it’s basic, and things are a bit clustered up, but it’s a decent map. There are ways to zoom to your study area, and you would probably want to play with the scale bar and north arrow a bit, but overall it’s functional and was pretty easy to create. On to a fancier map using the ggplot framework!
GGPLOT2 Map (ggmap)
Often we want to add a background to our map, some terrain, satellite imagery, et. Thankfully there are a number of easy options to do this using the ggmap package. We just need to assign a location, and appropriate zoom level. Using the get_map command we can take a look at several different types of layers, including watercolor, toner, terrain, and satellite. The cowplot package is a great way to plot/arrange ggplots.
Once we have settled on an appropriate background, we can move forward with our ggmap. When using shapefiles or spatial data in ggplot, the structure is slightly different. Importantly you’ll need to fortify() your spatial data so ggplot can read/plot it. Also, typically you need to specify the group and fill commands in the aes() call.
Adding the Pieces Together
A nice map should always have a north arrow and scale bar (in my opinion). Labels should be clear. It’s also nice to have some sort of inset so you can figure out where the map fits in the big picture. So let’s do that below! So close…this is the part that takes a bit of tweaking, but it’s pretty quick once you have the code set up. I’m using the ggsn package below to add the North arrow and scale bar. To add the overview map, I’m wrapping the map/mapdata commands in a map_data function to make it a ggmap. Unforunately there seems to be a glitch in the north arrow function, and I can’t pass that plot to the next step as a ggplot/ggmap object. It works, but it’s the end point if using the ggsn package.
Now let’s add an inset map and arrange things:
And the final product should look something like this, which is decent, not great but hope it’s useful!