1

I am trying to specify a simple legend for a map of polygons and an integer variable, in which not all values within the range are present. I need this in order to have the same legend, with the same color scale, on comparable maps which differ in both the range and the particular values present. For example, the maximum value of a variable is 8 on any of the maps. I want the legend to show the values 0 to 8 even when 6, or any particular value, is not present for any polygon, and I want the labels on the legend to be 0 to 8, inclusive, with no pooling.

A replicable example:

library(tmap)
library(dplyr)
library(sf)
set.seed(1234)

shape <- st_read(system.file("shape/nc.shp", package ="sf")) %>% 
  st_transform(shape, crs = 4326)
shape$myvar <- as.integer(sample(x=c(c(base::rep(c(0,1,2,3,4),16),base::rep(5,15),c(7,7,7,7,8)))))

table(shape$myvar)
0  1  2  3  4  5  7  8 
16 16 16 16 16 15  4  1 

I have tried many variations, but can't in this case get nine categories, with the corresponding labels.

mymap <- tm_shape(shape) +
  tm_fill(col = "myvar",
          style = "cat",
          breaks = c(0,1,2,3,4,5,6,7,8),
          n=9)
mymap

Map legend missing value 6

This legend is missing value 6.

In contrast, using the style = 'fixed' option like this:

mymap <- tm_shape(shape) +
  tm_fill(col = "myvar",
          style = "fixed",
          breaks = c(0,1,2,3,4,5,6,7,8),
          n=9)
mymap

Map_w_style_fixed

The legend here has a category for the value '6', but pools the last two categories.

I tried putting an additional argument into tm_fill:

 style.args = classIntervals(var=shape$myvar,n=9)

This didn't change the output from the previous map.

Try as I might, I can't get all 9 categories.

Could someone please give me some suggestions as to how to get the simple legend I want, without having to use GIMP?

Sunderam Dubey
  • 1
  • 11
  • 20
  • 40
Peter Pearman
  • 129
  • 1
  • 10

1 Answers1

1

Please find below one possible solution using tmap:

Reprex

  • Your data
library(tmap)
library(dplyr)
library(sf)

set.seed(1234)

shape <- st_read(system.file("shape/nc.shp", package ="sf")) %>% 
  st_transform(shape, crs = 4326)
shape$myvar <- as.integer(sample(x=c(c(base::rep(c(0,1,2,3,4),16),base::rep(5,15),c(7,7,7,7,8)))))
  • Suggested code
mymap <- tm_shape(shape) +
  tm_fill(col = "myvar",
          style = "fixed",
          breaks = c(0,1,2,3,4,5,6,7,8,+Inf), 
          labels = c("0","1","2","3","4","5","6","7","8")) +
  tm_layout(inner.margins = c(0.02, 0.08, 0.02, 0.02))

mymap

enter image description here

Created on 2022-03-04 by the reprex package (v2.0.1)

lovalery
  • 4,524
  • 3
  • 14
  • 28
  • 1
    Without the +Inf value in breaks(), the number of displayed categories in the legend drops to eight. Without the labels statement, the last label in the legend is '8 or more'. Both +Inf and the labels= elements are necessary to get the correct legend. I confirmed that even changing the values in the data (converting the last '8' to '7') does not change the number of categories in the legend. Thanks a lot! – Peter Pearman Mar 04 '22 at 15:24
  • @Peter Pearman thank you very much for your feedback. Glad that I could help. Cheers. – lovalery Mar 04 '22 at 18:52