Map coloring: the color scale styles available in the tmap package
Tags: rstats, spatial, tmap, maps
Published: 2020-01-19 08:52:30

---
title: Map coloring: the color scale styles available in the tmap package
published: true
date: 2019-10-17 00:00:00 UTC
tags: rstats, spatial, tmap, maps
canonical_url: 
---

This vignette builds on the [making maps chapter](https://geocompr.robinlovelace.net/adv-map.html) of [the Geocomputation with R book](https://geocompr.github.io/). Its goal is to demonstrate all possible map styles available in the **tmap** package.

## Prerequisites

The examples below assume the following packages are attached:

```
library(spData) # example datasets
library(tmap) # map creation
library(sf) # spatial data reprojection
```

The `world` object containing a world map data from [Natural Earth](https://www.naturalearthdata.com/) and information about countries’ names, regions, and subregions they belong to, areas, life expectancies, and populations. This object is in geographical coordinates using the WGS84 datum, however, for mapping purposes, the Mollweide projection is a better alternative (learn more in [the modifying map projections section](https://geocompr.robinlovelace.net/reproj-geo-data.html#modifying-map-projections)). The `st_tranform` function from the **sf** package allows for quick reprojection to the selected coordinate reference system (e.g., `"+proj=moll"` represents the Mollweide projection).

```
world_moll = st_transform(world, crs = "+proj=moll")
```

# One color

Let’s start with the basics. To create a simple world map, we need to specify the data object (`world_moll`) inside the `tm_shape()` function, and the way we want to visualize it. The **tmap** package offers several visualisation possibilities for polygons, including `tm_borders()`, `tm_fill()`, and `tm_polygons()`. The last one draws the filled polygons with borders, where the fill color can be specified with the `col` argument:

```
tm_shape(world_moll) +
  tm_polygons(col = "lightblue")
```

![](https://geocompr.github.io/post/2019/tmap-styles_files/figure-html/unnamed-chunk-3-1.png)

The output is a map of world countries, where each country is filled with a light blue color.

# Coloring of adjacent polygons

The `col` argument is very flexible, and its action depends on the value provided. In the previous example, we provided a single color value resulting in a map with one color. To create a map, where adjacent polygons do not get the same color, we need to provide a keyword `"MAP_COLORS"`.

```
tm_shape(world_moll) +
  tm_polygons(col = "MAP_COLORS")
```

![](https://geocompr.github.io/post/2019/tmap-styles_files/figure-html/unnamed-chunk-4-1.png)

The default color can be changed using the `palette` argument - run the `tmaptools::palette_explorer()` function to see possible palettes’ names.

```
tm_shape(world_moll) +
  tm_polygons(col = "MAP_COLORS",
              palette = "Pastel1")
```

![](https://geocompr.github.io/post/2019/tmap-styles_files/figure-html/unnamed-chunk-5-1.png)

<!-- Additionally, the number of classes can be set using the `n` argument. -->

Additionally, in this case, it is possible to use the `minimize` argument, which triggers the internal algorithm to search for a minimal number of colors for visualization.

```
tm_shape(world_moll) +
  tm_polygons(col = "MAP_COLORS",
              minimize = TRUE)
```

![](https://geocompr.github.io/post/2019/tmap-styles_files/figure-html/unnamed-chunk-6-1.png)

The new map uses five colors<!-- except for Angola (blue color)-->. On a side note, in theory, no more than four colors are required to color the polygons of the map so that no two adjacent polygons have the same color (learn more about the four color map theorem on [Wikipedia](https://en.wikipedia.org/wiki/Four_color_theorem)).

# Categorical maps

The third use of the `col` argument is by providing the variable (column) name. In this case, the map will represent the given variable. By default, **tmap** behaves differently depending on the input variable type. For example, it will create a categorical map when the provided variable contains characters or factors. The `tm_polygons(col = "subregion", style = "cat")` code will be run automatically in this case.

```
tm_shape(world_moll) +
  tm_polygons(col = "subregion")+
  tm_layout(legend.outside = TRUE)
```

![](https://geocompr.github.io/post/2019/tmap-styles_files/figure-html/unnamed-chunk-7-1.png)

# Discrete maps

Discrete maps represents continuous numerical variables using discrete class intervals. There are several ways to convert continuous variables to discrete ones implemented in **tmap**.

## Pretty

When the variable provided as the `col` argument is numeric, **tmap** will use the `"pretty"` style as a default. In other words, it runs `tm_polygons(col = "lifeExp", style = "pretty")` invisibly to the user. This style rounds breaks into whole numbers where possible and spaces them evenly.

```
tm_shape(world_moll) +
  tm_polygons(col = "lifeExp",
              legend.hist = TRUE) +
  tm_layout(legend.outside = TRUE)
```

![](https://geocompr.github.io/post/2019/tmap-styles_files/figure-html/unnamed-chunk-8-1.png)

A histogram is added using `legend.hist = TRUE` in this and several next examples to show how the selected map style relates to the distribution of values.

It is possible to indicate a preferred number of classes using the `n` argument. Importantly, not every `n` is possible depending on the range of the values in the data.

```
tm_shape(world_moll) +
  tm_polygons(col = "lifeExp",
              legend.hist = TRUE,
              n = 4) +
  tm_layout(legend.outside = TRUE)
```

![](https://geocompr.github.io/post/2019/tmap-styles_files/figure-html/unnamed-chunk-9-1.png)

## Fixed

The `"jenks"` style allows for a manual selection of the breaks in conjunction with the `breaks` argument.

```
tm_shape(world_moll) +
  tm_polygons(col = "lifeExp", 
              style = "fixed",
              breaks = c(45, 60, 75, 90),
              legend.hist = TRUE) +
  tm_layout(legend.outside = TRUE)
```

![](https://geocompr.github.io/post/2019/tmap-styles_files/figure-html/unnamed-chunk-10-1.png)

Additionally, the default labels can be overwritten using the `labels` argument.

```
tm_shape(world_moll) +
  tm_polygons(col = "lifeExp", 
              style = "fixed",
              breaks = c(45, 60, 75, 90),
              labels = c("low", "medium", "high"),
              legend.hist = TRUE) +
  tm_layout(legend.outside = TRUE)
```

![](https://geocompr.github.io/post/2019/tmap-styles_files/figure-html/unnamed-chunk-11-1.png)

## Breaks based on the standard deviation value

The `"sd"` style calculates a standard deviation of a given variable, and next use this value as the break width.

```
tm_shape(world_moll) +
  tm_polygons(col = "lifeExp", 
              style = "sd",
              legend.hist = TRUE) +
  tm_layout(legend.outside = TRUE)
```

![](https://geocompr.github.io/post/2019/tmap-styles_files/figure-html/unnamed-chunk-12-1.png)

## Fisher algorithm

The `"fisher"` style creates groups with maximalized homogeneity.<sup>1</sup>

```
tm_shape(world_moll) +
  tm_polygons(col = "lifeExp",
              style = "fisher",
              legend.hist = TRUE) +
  tm_layout(legend.outside = TRUE)
```

![](https://geocompr.github.io/post/2019/tmap-styles_files/figure-html/unnamed-chunk-13-1.png)

## Jenks natural breaks

The `"jenks"` style identifies groups of similar values in the data and maximizes the differences between categories.<sup>2</sup>

```
tm_shape(world_moll) +
  tm_polygons(col = "lifeExp",
              style = "jenks",
              legend.hist = TRUE) +
  tm_layout(legend.outside = TRUE)
```

![](https://geocompr.github.io/post/2019/tmap-styles_files/figure-html/unnamed-chunk-14-1.png)

## Hierarchical clustering

In the `"hclust"` style, breaks are created using hierarchical clustering.<sup>3</sup>

```
tm_shape(world_moll) +
  tm_polygons(col = "lifeExp",
              style = "hclust",
              legend.hist = TRUE) +
  tm_layout(legend.outside = TRUE)
```

![](https://geocompr.github.io/post/2019/tmap-styles_files/figure-html/unnamed-chunk-15-1.png)

## Bagged clustering

The `"bclust"` style uses the `bclust` function to generate the breaks using bagged clustering.<sup>4</sup>

```
tm_shape(world_moll) +
  tm_polygons(col = "lifeExp",
              style = "bclust",
              legend.hist = TRUE) +
  tm_layout(legend.outside = TRUE)
```

![](https://geocompr.github.io/post/2019/tmap-styles_files/figure-html/unnamed-chunk-16-1.png)

```
## Committee Member: 1(1) 2(1) 3(1) 4(1) 5(1) 6(1) 7(1) 8(1) 9(1) 10(1)
## Computing Hierarchical Clustering
```

## k-means clustering

The `"kmeans"` style uses the `kmeans` function to generate the breaks.<sup>5</sup>

```
tm_shape(world_moll) +
  tm_polygons(col = "lifeExp", 
              style = "kmeans",
              legend.hist = TRUE) +
  tm_layout(legend.outside = TRUE)
```

![](https://geocompr.github.io/post/2019/tmap-styles_files/figure-html/unnamed-chunk-17-1.png)

## Quantile breaks

The `"quantile"` style creates breaks with an equal number of features (polygons).

```
tm_shape(world_moll) +
  tm_polygons(col = "lifeExp", 
              style = "quantile",
              legend.hist = TRUE) +
  tm_layout(legend.outside = TRUE)
```

![](https://geocompr.github.io/post/2019/tmap-styles_files/figure-html/unnamed-chunk-18-1.png)

## Equal breaks

The `"equal"` style divides input values into bins of equal range and is appropriate for variables with a uniform distribution. It is not recommended for variables with a skewed distribution as the resulting map may end-up having little color diversity.

```
tm_shape(world_moll) +
  tm_polygons(col = "lifeExp", 
              style = "equal",
              legend.hist = TRUE) +
  tm_layout(legend.outside = TRUE)
```

![](https://geocompr.github.io/post/2019/tmap-styles_files/figure-html/unnamed-chunk-19-1.png)

Learn more about the implementation of discrete scales in [the **classInt** package’s documentation](https://r-spatial.github.io/classInt/index.html).

# Continuous maps

The **tmap** package also allows for creating continuous maps.

## Continuous

The `"cont"` style presents a large number of colors over the continuous color field.

```
tm_shape(world_moll) +
  tm_polygons(col = "lifeExp",
              style = "cont") +
  tm_layout(legend.outside = TRUE)
```

![](https://geocompr.github.io/post/2019/tmap-styles_files/figure-html/unnamed-chunk-20-1.png)

## Order

The `"order"` style also presents a large number of colors over the continuous color field. However, this style is suited to visualize skewed distributions; notice that the values on the legend do not change linearly.

```
tm_shape(world_moll) +
  tm_polygons(col = "lifeExp",
              style = "order") +
  tm_layout(legend.outside = TRUE)
```

![](https://geocompr.github.io/post/2019/tmap-styles_files/figure-html/unnamed-chunk-21-1.png)

# Logarithmic scales

The default numeric style, `pretty`, is easy to understand, but it is not proper for maps of variables with skewed distributions.

```
tm_shape(world_moll) +
  tm_polygons(col = "pop") +
  tm_layout(legend.outside = TRUE)
```

![](https://geocompr.github.io/post/2019/tmap-styles_files/figure-html/unnamed-chunk-22-1.png)

Another possible style, `order` works better in this case; however, it is not easy to interpret.

```
tm_shape(world_moll) +
  tm_polygons(col = "pop", 
              style = "order") +
  tm_layout(legend.outside = TRUE)
```

![](https://geocompr.github.io/post/2019/tmap-styles_files/figure-html/unnamed-chunk-23-1.png)

A better alternative, in this case, is to use a common logarithm (the logarithm to base 10) scale. The **tmap** package gives two possibilities in this case - `"log10_pretty"` and `"log10"`. The `"log10_pretty"` style is a common logarithmic version of the regular `pretty` style.

```
tm_shape(world_moll) +
  tm_polygons(col = "pop", 
              style = "log10_pretty") +
  tm_layout(legend.outside = TRUE)
```

![](https://geocompr.github.io/post/2019/tmap-styles_files/figure-html/unnamed-chunk-24-1.png)

On the other hand, the `"log10"` style is a version of a continuous scale.

```
tm_shape(world_moll) +
  tm_polygons(col = "pop", 
              style = "log10") +
  tm_layout(legend.outside = TRUE)
```

![](https://geocompr.github.io/post/2019/tmap-styles_files/figure-html/unnamed-chunk-25-1.png)

# Conclusions

Selecting a color scale style is not an easy task. It depends on the type of input variable and its distribution, but also the intended audience. Therefore, it is worth to spend some time and think about your readers (e.g., would they be able to understand the logarithmic scale or should you use the manual breaks instead?) and your data (e.g., how many breaks should there be to show different subgroups?). Now you know different color scale styles implemented in **tmap** , so let’s try using them for your own projects!

* * *

1. [https://www.tandfonline.com/doi/abs/10.1080/01621459.1958.10501479](https://www.tandfonline.com/doi/abs/10.1080/01621459.1958.10501479)↩

2. [https://en.wikipedia.org/wiki/Jenks\_natural\_breaks\_optimization](https://en.wikipedia.org/wiki/Jenks_natural_breaks_optimization)↩

3. See the `?hclust` documentation for more details.↩

4. See the `?bclust` documentation for more details.↩

5. See the `?kmeans` documentation for more details.↩