R Maps in Microsoft Power BI: Small Multiples

R Maps in Microsoft Power BI: Small Multiples
Reading Time: 5 minutes

After an initial introduction to R maps in Power BI, let’s explore another topic: small multiples. This technique is used to make comparisons by showing variations of the same map plotted together in a grid. It is not limited to maps though. Nearly every type of plot could work well when viewed as a small multiple.

Small multiples by year

 

Small multiples are an effective way to visualize categorical differences. Using the same dataset, which contains airfield locations in the Great Lakes region of the United States, what happens if we want to map their ownership? These airfields could be public, private, or military.

One way to show the difference in ownership would be to employ unique shapes for the points on the map. For example, plot private airports as circles, public ones as crosses, etc. Another method could be to use point size (although that leads to another issue since point area is typically used to display quantified information rather than categorical). Still another way would be to use different colors. If you have more than a few categories though, these methods tend to rapidly lose value.

For example, even with four categories, is color effective? Mixed in with the numerous green public and blue private airfields, can you easily find the army and air force bases in the map below? HINT: army bases are red and air force bases are black.

Categorical

 

Now, try finding the army and air force bases in the following image that employs multiples. HINT: they are in the maps separately labeled “Army” and “Air Force”.

Small multiples sample.png

 

By splitting the map into a multifaceted one, we can more easily see the locations of the military airfields. We can also see that private airfields seem to greatly outnumber public ones. That type of discernment is largely lost when using color or shape to show variation.

How do we obtain the small multiple effect using R in Power BI? 

Please note that if you are using a plotting package like ggplot2, there is an easier way than the technique outlined below. The  following steps are helpful for packages without built-in support. You may also try the lattice package.

In the previous tutorial, we saw how it was possible to display two maps in the same R visual. To do this, we used mfrow=c(1,2) to create a matrix allowing different maps to be placed alongside each other in one row and two columnsIn that scenario, we plotted an overview of the United States next to a more focused map of the Great Lakes region.

County

 

Is that overview/inset view a true example of a small multiple? No. While the R visual is multifaceted, the map of the United States paired with the Great Lakes presents the same information at a different level. That image is a start though, and we can achieve the desired result with only a few changes to the existing R code.

First, let’s look at how we can adjust the grid by splitting out the states. Initially, we will alter mfrow to create two rows and three columns by changing the values to mfrow=c(2,3). Then, instead of having dataset$State in the map() function, we split it out into a vector of unique values that we’ll call states. The final step is key. Instead of manually creating a map for each state, we will add a for loop and iterate over the distinct values in states.

library(maps)
library(mapproj)
par(mfrow=c(2,3), mar=c(0,0,0,0))
elevationMax <- max(dataset$Elevation)
states <- unique(dataset$State)
for(i in states){
    map("county", i, col="#01B8AA", bg="#374649", proj="albers", param=c(39,45))
    points(mapproject(dataset$Longitude, dataset$Latitude), col=NA, bg="#F2C80F", pch=21, cex=dataset$Elevation / elevationMax * 0.8)
}

Small multiples without moving points
The five separate states now appear in the grid, but the airfield points plotted incorrectly! The reason that happened is because we accounted for distinct values in map() but not in points(). By using subset within the for loop though, we can filter the airfields so that only the appropriate ones are plotted with each state.

library(maps)
library(mapproj)
par(mfrow=c(2,3), mar=c(0,0,0,0))
elevationMax <- max(dataset$Elevation)
states <- unique(dataset$State)
for(i in states){
    filteredForState <- subset(dataset, dataset$State == i)
    map("county", i, col="#01B8AA", bg="#374649", proj="albers", param=c(39,45))
    points(mapproject(filteredForState$Longitude, filteredForState$Latitude), col=NA, bg="#F2C80F", pch=21, cex=dataset$Elevation / elevationMax * 0.8)
}

Small multiples points moved.PNG

 

We have now seen how to plot the states separately using the for loop and a subset of the data for each state, and that same logic can be applied for ownership or any other category. Instead of obtaining unique “State” values and filtering for state, simply get the unique “OwnerType” values and filter for owner type. Since there are only four owner types, we will also change mfrow to a 2×2 grid.

library(maps)
library(mapproj)
par(mfrow=c(2,2), mar=c(0,0,0,0))
elevationMax <- max(dataset$Elevation)
ownership <- unique(dataset$OwnerType)
for(i in ownership){
    filteredForOwnership <- subset(dataset, dataset$OwnerType == i)
    map("county", dataset$State, col="#01B8AA", bg="#374649", proj="albers", param=c(39,45))
    points(mapproject(filteredForOwnership$Longitude, filteredForOwnership$Latitude), col=NA, bg="#F2C80F", pch=21, cex=dataset$Elevation / elevationMax * 0.8)
}

Small multiples.PNG

 

We are almost there! In order to differentiate between types, let’s add a title for each of the maps using title(). To allow more room to display the title, we will also change the margins around each image from 0 to 1 using mar=c(1,1,1,1). Finally, to make the airfield points easier to see, let’s remove the county boundaries by changing county to state. We could further refine point size to make the military bases stand out more, but hopefully you get the idea.

library(maps)
library(mapproj)
par(mfrow=c(2,2), mar=c(1,1,1,1))
elevationMax <- max(dataset$Elevation)
ownership <- unique(dataset$OwnerType)
for(i in ownership){
    filteredForOwnership <- subset(dataset, dataset$OwnerType == i)
    map("state", dataset$State, col="#01B8AA", bg="#374649", proj="albers", param=c(39,45))
    points(mapproject(filteredForOwnership$Longitude, filteredForOwnership$Latitude), col=NA, bg="#F2C80F", pch=21, cex=dataset$Elevation / elevationMax)
    title(i, col.main="#FFFFFF")
}

Small multiples with title.PNG

 

In the context of the greater Power BI report, filtering works as it would if you had one map instead of multiple ones.

Small multiples full report.PNG

Small multiples full report filtered.PNG

 

Particularly if you have numerous categories, small multiples are an effective way to display your data. Their value is apparent whether you have four categories or forty. Remember as well that although we explored small multiples within the context of maps, they can be a great tool to use with other types of R plots.

 

Like the last tutorial, I have posted the PBIX file for Power BI Desktop on GitHub. Feel free to download it and experiment with the code for the R visual. Also, if you would like to discuss how you might be able to more effectively use Power BI within your organization, contact my employer, BlueGranite.

 

 




Leave a Reply

%d bloggers like this: