Join the R Community at ShinyConf 2023

Visualizing spatial data in R with the ggmap R package

R ggmap – How to Visualize Spatial Data in R


Spatial data is always tougher to visualize than it seems at first. Well, not anymore. R ggmap is an amazing package you can start using almost instantly, after some light configuration. It won’t take you more than a couple of minutes to configure everything and have your first map ready.

Today you’ll learn how to use the ggmap package to do almost everything geodata-related. We’ll kick things off by plotting basic maps, markers, and paths, and then dive into changing map themes. Once that’s under our belt, we’ll focus on advanced topics, including geocoding, reverse geocoding, drawing routes, and calculating distance between locations.

Want to build interactive Google Maps? Here’s a complete guide for interactive Google Maps in Shiny.

Table of contents:


Introduction to R ggmap Package

First things first, there’s a bit of setup we have to go over. ggmap uses Google Maps behind the scenes, so you’ll need an active Google Cloud Platform account. You’ll also have to set up billing, as it’s required for their mapping APIs. Don’t worry, GCP won’t charge you a penny without your knowledge.

Is the account ready? Great, now enable the following APIs under APIs & Services – Library:

  • Maps JavaScript API
  • Maps Static API
  • Geocoding API

These are required to establish a connection between R and Google Maps. The final step is to create a new API key. Go under Credentials and click on + Create credentials to get a new API key. Ours looks like this:

Image 1 - Google Cloud Platform Maps API key

Image 1 – Google Cloud Platform Maps API key

That’s all you need from GCP. Now head over to RStudio and install ggmap with the following command:

install.packages("ggmap")

The last step in the configuration process is to connect R and Google Maps. That’s done with the API key you’ve just created. Make sure to specify write = TRUE so you don’t have to call this function ever again:

ggmap::register_google(key = "<your-api-key>", write = TRUE)
Image 2 - Registering R ggmap with GCP

Image 2 – Registering R ggmap with GCP

That’s it! Let’s verify the configuration succeeded. The following code snippet uses the get_googlemap() function to draw a map at a specific location. No latitude/longitude pairs are required (but you can use them), just specify the location string:

library(ggmap)

get_googlemap(center = "New York") %>% ggmap()

The map looks familiar, at least if you’ve used Google Maps in the past:

Image 3 - Basic ggmap map of New York City

Image 3 – Basic ggmap map of New York City

To get a satellite view instead, add an additional maptype argument and set it to satellite:

get_googlemap("New York", zoom = 12, maptype = "satellite") %>% ggmap()
Image 4 - Satellite map of New York City

Image 4 – Satellite map of New York City

There’s also a hybrid option available, which will show a satellite view with roads, labels, and points of interest.

You have to admit – drawing a basic map was pretty easy. Let’s complicate things slightly next.

Plot Points and Paths with R ggmap

Most of the time, you want to display markers or paths on your spatial visualizations. Maybe you want to map out school locations in a specific city or draw a line from one point to the other. Whatever the case might be, this section has you covered.

Working with GPX files? Learn how to read and visualize GPX files in R.

To avoid downloading any datasets, we’ll create a data.frame of 50 points scattered around (-74, 40.74) geolocation, which should be right around NYC. That’s done by combining jitter() and rep() functions:

set.seed(42)

point_df <- round(data.frame(
  x = jitter(rep(-74, 50), amount = 0.05),
  y = jitter(rep(40.74, 50), amount = 0.05)
), digits = 2)
head(point_df)

Here’s what the dataset looks like:

Image 5 - Creating a data.frame of random data points

Image 5 – Creating a data.frame of random data points

Those are the coordinates at which we’ll draw markers first. To do so, simply add another argument in a call to get_googlemap()markers, and pass the dataset as a value. It will automatically infer what’s what, so you don’t have to lift a finger:

get_googlemap(center = "New York", zoom = 12, markers = point_df, scale = 2) %>% ggmap()
Image 6 - Random data points as markers on the map

Image 6 – Random data points as markers on the map

The story is similar if you want to draw lines (path). For simplicity’s sake, let’s connect all the points instead of showing markers. Swap the markers attribute for path:

get_googlemap(center = "New York", zoom = 12, path = point_df, scale = 2) %>% ggmap()
Image 7 - Random data points as a path on the map

Image 7 – Random data points as a path on the map

The resulting map is messy, but you get the point. You can also use both markers and path in a single function call if you want to display both markers and lines.

With the basics out of the way, let’s see how we can spice the looks of the map.

How to Change the Map Type

The default map options (terrain, satellite, hybrid) aren’t the best fit for every use case. R and ggmap allow you to use several options for free. These are:

  • stamen.toner
  • stamen.watercolor
  • stamen.terrain-background
  • stamen.toner-lite

We’ll show you what the first two look like. You have to use a different function this time – qmap() – it serves as a wrapper for ggmap and get_map. Two new parameters are needed, source and maptype. These represent the values shown in the above list.

Here’s an example of a map that uses stamen.toner map type:

qmap("New York", zoom = 12, scale = 2, source = "stamen", maptype = "toner")
Image 8 - Stamen Toner map type

Image 8 – Stamen Toner map type

It’s a neat black-and-white theme that definitely has its place on some reports and dashboards.

If you’re more interested in colorful options, look no further than stamen.watercolor:

qmap("New York", zoom = 12, scale = 2, source = "stamen", maptype = "watercolor")
Image 9 - Stamen Watercolor map type

Image 9 – Stamen Watercolor map type

This one’s best used when there’s a lot of water on a map because it colors it with a beautiful shade of blue.

As for the other two options – feel free to explore them on your own.

Advanced #1 – Geocoding and Reverse Geocoding with ggmap

Let’s dive into more advanced use cases of the R ggmap package. The first one isn’t at all tied to data visualization, but can come in handy in the right circumstances.

We’ll show you how you can use ggmap for geocoding and reverse geocoding operations. Put simply, geocoding returns geolocation (latitude and longitude) when given an address. Reverse geocoding goes from geolocation to an address.

In R, it boils down to a single function call:

  • ggmap::geocode() will convert an address into a latitude and longitude pair.
  • ggmap::revgeocode() will convert a vector of latitude and longitude values into one or multiple addresses, depending on how many decimal places you specify.

Let’s take a look at a geocoding example first:

geocode("20 W 34th St., New York")
Image 10 - Geocoding - from address to latitude and longitude

Image 10 – Geocoding – from address to latitude and longitude

Both latitude and longitude are returned but aren’t precise. These coordinates point to NYC, but without more decimal places you won’t be able to pinpoint the address.

As for reverse geocoding, ggmap tends to return multiple values when many objects of interest are nearby:

revgeocode(c(lon = -73.985428, lat = 40.748817))
Image 11 - Reverse geocoding - from latitude and longitude to address

Image 11 – Reverse geocoding – from latitude and longitude to address

The address of the Empire State Building should have been returned if you’re wondering.

Advanced #2 – Drawing Routes with ggmap

The second advanced ggmap use case has to do with drawing routes. What this package does for you is amazing – you can specify starting and ending points as strings, and use the trek() function to construct a route data frame. It will contain data points that when plotted will show an optimal driving route from one place to the other.

To start, we’ll create a route from Miami, FL to Austin, TX:

trek_df <- trek("miami, florida", "austin, texas", structure = "route")
head(trek_df)

Here’s what it looks like:

Image 12 - Creating a route dataset

Image 12 – Creating a route dataset

To draw a route, we’ll use the geom_path() function that acts just like any familiar method from 2 package. After all, ggmap was built on top of that package.

Here’s the entire code:

qmap(zoom = 4) + 
  geom_path(
    aes(x = lon, y = lat), color = "blue", size = 1, data = trek_df
  )
Image 13 - Plotting a route with ggmap

Image 13 – Plotting a route with ggmap

And there you have it – routing doesn’t get much easier.

Advanced #3 – Calculating Distances Between Locations

For the final advanced use case, we’ll take a look at distance calculation. The ggmap package has a mapdist() function which accepts at least two parameters:

  • from – a vector of strings, where each string represents a location (e.g., “miami, florida”).
  • to– a string that represents the destination (same format as above).

We’ll use this function to calculate distances from three locations to Austin, TX:

mapdist(c("miami, florida", "los angeles, california", "boulder, colorado"), "austin, texas")

The function returns a data frame that looks as follows:

Image 14 - Calculating distances between locations with ggmap

Image 14 – Calculating distances between locations with ggmap

You get absolutely everything you could ask for and more with this function – from meters, kilometers, and miles, to even estimated time of driving.

Starting to get a feel for R? Be sure you know these 7 essential R packages.

We’ve explored a lot of functionalities ggmap has to offer, so let’s make a short recap next.


Summary of R ggmap

In short, ggmap can easily become a central place for anything mapping related in R. It has everything you could ask for and more – from visualization options to geocoding, reverse geocoding, routing, and distance calculation. The only gotcha is that you need an active GCP account with billing enabled. You won’t get charged to a certain point, but Google APIs are nowhere near free for heavy usage. For personal projects, you should be able to manage in the free tier.

Ready to take your remote sensing game to the next level? Build your own solar panel detection app using AI and streamlit.

What’s your favorite ggmap feature that we haven’t covered? Is it your default mapping package, or have you opted for something else? Please let us know in the comment section below.

Want to visualize spatial data without a GCP account? Try Leaflet with our complete guide.