5  Mapping With R

5.1 Types of maps

The fonction mf_map() is the central function of the package mapsf (Giraud 2022a). It makes it possible to carry out most of the usual representations in cartography. These main arguments are:

  • x, an sf object ;
  • var, the name of variable to present ;
  • type, the type of presentation.

5.1.1 Create a simple map

The following lines import the spatial information layers located in the geopackage cambodia.gpkg file.

library(sf)

#Import Cambodia country border
country = st_read("data_cambodia/cambodia.gpkg", layer = "country", quiet = TRUE)
#Import provincial administrative border of Cambodia
education = st_read("data_cambodia/cambodia.gpkg", layer = "education", quiet = TRUE)
#Import district administrative border of Cambodia
district = st_read("data_cambodia/cambodia.gpkg", layer = "district", quiet = TRUE)
#Import roads data in Cambodia
road = st_read("data_cambodia/cambodia.gpkg", layer = "road", quiet = TRUE)
#Import health center data in Cambodia
hospital = st_read("data_cambodia/cambodia.gpkg", layer = "hospital", quiet = TRUE)
library(mapsf)

mf_map(x = district, border = "white")
mf_map(x = country,lwd = 2, col = NA, add = TRUE)
mf_map(x = road, lwd = .5, col = "ivory4", add = TRUE)
mf_map(x = hospital, pch = 20, cex = 1, col = "#FE9A2E", add = TRUE) 

5.1.2 Proportional symbol map

Proportional symbol maps are used to represent inventory variables (absolute quantitative variables, sum and average make sense). The function mf_map(..., type = "prop") proposes this representation.

#District
mf_map(x = district)     

# Proportional symbol 
mf_map(
  x = district, 
  var = "T_POP",
  val_max = 700000,
  type = "prop",
  col = "#148F77", 
  leg_title = "Population 2019"
)

# Title
mf_title("Distribution of population in provincial level")

5.1.2.1 Compare multiple map

It is possible to fix the dimensions of the largest symbol corresponding to a certain value with the arguments inches and val_max. We can use construct maps with comparable proportional symbols.

par(mfrow = c(1,2))   #Displaying two maps facing each other

#district
mf_map(x = district, border = "grey90", lwd = .5)    
# Add male Population
mf_map(
  x = district, 
  var = "Male", 
  type = "prop",
  col = "#1F618D",
  inches = 0.2, 
  val_max = 300000, 
  leg_title = "Male", 
  leg_val_cex = 0.5,
)
mf_title("Male Population by Distict")   #Adding map title

#district
mf_map(x = district, border = "grey90", lwd = .5)    
# Add female Population
mf_map(
  x = district, 
  var = "Female", 
  type = "prop",
  col = "#E74C3C",
  inches = 0.2, 
  val_max = 300000, 
  leg_title ="Female", 
  leg_val_cex = 0.5
)
mf_title("Female Population by Distict")     #Adding map title

Here we have displayed two maps facing each other, see the point Displaying several maps on the same figure for more details.

5.1.3 Choropleth map

Choropleth maps are used to represent ratio variables (relative quantitative variables, mean has meaning, sum has no meaning).

For this type of representation, you must first:

  • choose a discretization method to transform a continuous statistical series into classes defined by intervals,
  • choose a number of classes,
  • choose a color palette.

The function mf_map(…, type = “choro”)makes it possible to create choroplete maps. The arguments nbreaks and breaks are used to parameterize the discretizations, and the function mf_get_breaks() makes it possible to work on the discretizations outside the function mf_map(). Similarly, the argument palis used to fill in a color palette, but several functions can be used to set the palettes apart from the (mf_get_pal…) function.

# Population density (inhabitants/km2) using the sf::st_area() function
district$DENS <- 1e6 * district$T_POP / as.numeric(st_area(district))   #Calculate population density 
mf_map(
  x = district,
  var = "DENS",
  type = "choro",
  breaks = "quantile",
  pal = "BuGn",
  lwd = 1,
  leg_title = "Distribution of population\n(inhabitants per km2)", 
  leg_val_rnd = 0
)
mf_title("Distribution of the population in (2019)")

cases = st_read("data_cambodia/cambodia.gpkg", layer = "cases", quiet = TRUE) # load cases layer
cases = subset(cases, Disease == "W fever") # subset data to only keep W fever cases
population <- read.csv("data_cambodia/khm_admpop_adm2_2016_v2.csv") # read population data
population <- population[, c("ADM2_PCODE", "T_TL")] # just select few columns
population$T_TL <- as.numeric(gsub(",","",population$T_TL)) # Remove commas (not supposed to be in the dataframe)
district$cases <- lengths(st_intersects(district, cases)) # count points in polygons
district <- merge(district,
                  population,
                  by = "ADM2_PCODE") # merge shape with population data
district$incidence <- district$cases / district$T_TL * 100000 # calculate incidence

mf_map(x = district,
       var = "incidence",
       type = "choro",
       leg_title = "Incidence (per 100 000)")
mf_layout(title = "Incidence of W Fever in Cambodia")

5.1.3.1 Discretisation

The fonction mf_get_breaks() provides the methods of discretization of classic variables: quantiles, average/standard deviation, equal amplitudes, nested averages, Fisher-Jenks, geometric, etc.

education$enrol_g_pct = 100 * education$enrol_girl/education$t_enrol   #Calculate percentage of enrolled girl student

d1 = mf_get_breaks(education$enrol_g_pct, nbreaks = 6, breaks = "equal", freq = TRUE)
d2 = mf_get_breaks(education$enrol_g_pct, nbreaks = 6, breaks = "quantile")
d3 = mf_get_breaks(education$enrol_g_pct, nbreaks = 6, breaks = "geom")
d4 = mf_get_breaks(education$enrol_g_pct, breaks = "msd", central = FALSE)

5.1.3.2 Color palettes

The argument pal de mf_map() is dedicated to choosing a color palette. The palettes provided by the function hcl.colors() can be used directly.

mf_map(x = education, var = "enrol_g_pct", type = "choro",
       breaks = d3, pal = "Reds 3")

The fonction mf_get_pal() allows you to build a color palette. This function is especially useful for creating balanced asymmetrical diverging palettes.

mypal <- mf_get_pal(n = c(4,6), palette = c("Burg", "Teal"))
image(1:10, 1, as.matrix(1:10), col=mypal, xlab = "", ylab = "", xaxt = "n",
      yaxt = "n",bty = "n")

5.1.3.3 For a point layer

It is possible to use this mode of presentation in specific implementation also.

dist_c <- st_centroid(district)
mf_map(district)
mf_map(
  x = dist_c,
  var = "DENS",
  type = "choro",
  breaks = "quantile",
  nbreaks = 5,
  pal = "PuRd",
  pch = 23,
  cex = 1.5,
  border = "white",
  lwd = .7,
  leg_pos = "topleft",
  leg_title = "Distribution of population\n(inhabitants per km2)", 
  leg_val_rnd = 0, 
  add = TRUE
)
mf_title("Distribution of population in (2019)")

5.1.4 Typology map

Typology maps are used to represent qualitative variables. The function mf_map(..., type = "typo") proposes this representation.

mf_map(
  x = district,
  var="Status",
  type = "typo",
  pal = c('#E8F9FD','#FF7396','#E4BAD4','#FFE3FE'),
  lwd = .7,
  leg_title = ""
)
mf_title("Administrative status by size of area")

5.1.4.1 Ordering value in the legend

The argument val_order is used to order the categories in the

mf_map(
  x = district,
  var="Status",
  type = "typo",
  pal = c('#E8F9FD','#FF7396','#E4BAD4','#FFE3FE'),
  val_order = c("1st largest district", "2nd largest district", "3rd largest district","<4500km2"),
  lwd = .7,
  leg_title = ""
)
mf_title("Administrative status by size of area")

5.1.4.2 Map of point

When the implantation of the layer is punctual, symbols are used to carry the colors of the typology.

#extract centroid point of the district
dist_ctr <- st_centroid(district[district$Status != "<4500km2", ])
mf_map(district)
mf_map(
  x = dist_ctr,
  var = "Status",
  type = "typo",
  cex = 2,
  pch = 22,
  pal = c('#FF7396','#E4BAD4','#FFE3FE'),
  leg_title = "",
  leg_pos = "bottomright",
  add = TRUE
)
mf_title("Administrative status by size of area")

5.1.4.3 Map of lines

#Selection of roads that intersect the city of Siem Reap
pp <- district[district$ADM1_EN == "Phnom Penh", ]
road_pp <- road[st_intersects(x = road, y = pp, sparse = FALSE), ]
mf_map(pp)
mf_map(
  x = road_pp,
  var = "fclass",
  type = "typo",
  lwd = 1.2,
  pal = mf_get_pal(n = 6, "Tropic"),
  leg_title = "Types of road",
  leg_pos = "topright",
  leg_frame = T,
  add = TRUE
)
mf_title("Administrative status")

5.1.5 Map of stocks and ratios

The function mf_map(..., var = c("var1", "var2"), type = "prop_choro") represents proportional symbols whose areas are proportional to the values of one variable and whose color is based on the discretization of a second variable. The function uses the arguments of the functions mf_map(..., type = "prop") and mf_map(..., type = "choro").

mf_map(x = district)
mf_map(
  x = district,
  var = c("T_POP", "DENS"),
  val_max = 500000,
  type = "prop_choro",
  border = "grey60",
  lwd = 0.5,
  leg_pos = c("bottomright", "bottomleft"),
  leg_title = c("Population", "Density of\n population\n(inhabitants per km2)"),
  breaks = "q6",
  pal = "Blues 3",
  leg_val_rnd = c(0,1))
mf_title("Population")

5.1.6 Map of stocks and categories

The function mf_map(..., var = c("var1", "var2"), type = "prop_typo") represents proportional symbols whose areas are proportional to the values of one variable and whose color is based on the discretization of a second variable. The function uses the arguments of the mf_map(..., type = "prop") and function mf_map(..., type = "typo").

mf_map(x = district)
mf_map(
  x = district,
  var = c("Area.Km2.", "Status"),
  type = "prop_typo",
  pal = c('#E8F9FD','#FF7396','#E4BAD4','#FFE3FE'),
  val_order = c("<4500km2","1st largest district", "2nd largest district", "3rd largest district"),
  leg_pos = c("bottomleft","topleft"),
  leg_title = c("Population\n(2019)",
                "Statut administratif"),
)
mf_title("Population")

5.2 Layout

To be finalized, a thematic map must contain certain additional elements such as: title, author, source, scale, orientation…

5.2.1 Example data

The following lines import the spatial information layers located in the geopackage cambodia.gpkg file.

library(sf)
country = st_read("data_cambodia/cambodia.gpkg", layer = "country", quiet = TRUE)         #Import Cambodia country border
education = st_read("data_cambodia/cambodia.gpkg", layer = "education", quiet = TRUE)     #Import provincial administrative border of Cambodia
district = st_read("data_cambodia/cambodia.gpkg", layer = "district", quiet = TRUE)       #Import district administrative border of Cambodia
road = st_read("data_cambodia/cambodia.gpkg", layer = "road", quiet = TRUE)               #Import roads data in Cambodia
hospital = st_read("data_cambodia/cambodia.gpkg", layer = "hospital", quiet = TRUE)       #Import hospital data in Cambodia
cases = st_read("data_cambodia/cambodia.gpkg", layer = "cases", quiet = TRUE)             #Import example data of fever_cases in Cambodia

5.2.2 Themes

The function mf_theme() defines a cartographic theme. Using a theme allows you to define several graphic parameters which are then applied to the maps created with mapsf. These parameters are: the map margins, the main color, the background color, the position and the aspect of the title. A theme can also be defined with the mf_init() and function mf_export().

5.2.2.1 Use a predefined theme

A series of predefined themes are available by default (see ?mf_theme).

library(mapsf)
# use of a background color for the figure, to see the use of margin
opar <- par(mfrow = c(2,2))
# Using a predefined theme
mf_theme("default")
mf_map(district)
mf_title("Theme : 'default'")

mf_theme("darkula")
mf_map(district)
mf_title("Theme : 'darkula'")

mf_theme("candy")
mf_map(district)
mf_title("Theme : 'candy'")

mf_theme("nevermind")
mf_map(district)
mf_title("Theme : 'nevermind'")
par(opar)

5.2.2.2 Modify an existing theme

It is possible to modify an existing theme. In this example, we are using the “default” theme and modifying a few settings.

library(mapsf)
opar <- par(mfrow = c(1,2))
mf_theme("default")
mf_map(district)
mf_title("default")

mf_theme("default", tab = FALSE, font = 4, bg = "grey60", pos = "center")
mf_map(district)
mf_title("modified default")
par(opar)

5.2.2.3 Create a theme

It is also possible to create a theme.

mf_theme(
  bg = "lightblue",    # background color
  fg = "tomato1",      # main color
  mar = c(1,0,1.5,0),  # margin
  tab = FALSE,         # "tab" style for the title
  inner = FALSE,       # title inside or outside of map area
  line = 1.5,          # space dedicated to title
  pos = "center",      # heading position
  cex = 1.5,           # title size
  font = 2             # font types for title
)
mf_map(district)
mf_title("New theme")

5.2.3 Titles

The function mf_title() adds a title to a map.

mf_theme("default")
mf_map(district)
mf_title("Map title")

It is possible to customize the appearance of the title

mf_map(district)
mf_title(
  txt = "Map title", 
  pos = "center", 
  tab = FALSE, 
  bg = "tomato3", 
  fg = "lightblue", 
  cex = 1.5, 
  line = 1.7, 
  font = 1, 
  inner = FALSE
)

5.2.4 Arrow orientation

The function mf_arrow() allows you to choose the position and aspect of orientation arrow.

mf_map(district)
mf_arrow()

5.2.5 Scale

The function mf_scale() allows you to choose the position and the aspect of the scale.

mf_map(district)
mf_scale(
  size = 60,
  lwd = 1,
  cex = 0.7
)

5.2.6 Credits

The function mf_credits() displays a line of credits (sources, author, etc.).

mf_map(district)
mf_credits("IRD\nInstitut Pasteur du Cambodge, 2022")

5.2.7 Complete dressing

The function mf_layout() displays all these elements.

mf_map(district)
mf_layout(
  title = "Cambodia",
  credits = "IRD\nInstitut Pasteur du Cambodge, 2022",
  arrow = TRUE
)

5.2.8 Annotations

mf_map(district)
mf_annotation(district[district$ADM2_EN == "Bakan",], txt = "Bakan", col_txt = "darkred", halo = TRUE, cex = 1.5)

5.2.9 Legends

mf_map(district)
mf_legend(
  type = "prop", 
  val = c(1000,500,200,10), 
  inches = .2, 
  title = "Population", 
  pos = "topleft"
)
mf_legend(
  type = "choro", 
  val = c(0,10,20,30,40),
  pal = "Greens", 
  pos = "bottomright", 
  val_rnd = 0
)

5.2.10 Labels

The function mf_label() is dedicated to displaying labels.

dist_selected <- district[st_intersects(district, district[district$ADM2_EN == "Bakan", ], sparse = F), ]

mf_map(dist_selected)
mf_label(
  x = dist_selected,
  var = "ADM2_EN",
  col= "darkgreen",
  halo = TRUE,
  overlap = FALSE, 
  lines = FALSE
)
mf_scale()

The argument halo = TRUE allows to display a slight halo around the labels and the argument overlap = FALSE allows to create non-overlapping labels.

5.2.11 Center the map on a region

The function mf_init() allows you to initialize a map by centering it on a spatial object.

mf_init(x = dist_selected)
mf_map(district, add = TRUE)
mf_map(dist_selected, col = NA, border = "#29a3a3", lwd = 2, add = TRUE)

5.2.12 Displaying several maps on the same figure

Here you have to use mfrow of the function par(). The first digit represents the number of of rows and second the number of columns.

# define the figure layout (1 row, 2 columns)
par(mfrow = c(1, 2))

# first map
mf_map(district)
mf_map(district, "Male", "prop", val_max = 300000)
mf_title("Population, male")

# second map
mf_map(district)
mf_map(district, "Female", "prop", val_max = 300000)
mf_title("Population, female")

5.2.13 Exporting maps

It is quite difficult to export figures (maps or others) whose height/width ratio is satisfactory. The default ratio of figures in png format is 1 (480x480 pixels):

dist_filter <- district[district$ADM2_PCODE == "KH0808", ]
png("img/dist_filter_1.png")
mf_map(dist_filter)
mf_title("Filtered district")
dev.off()

On this map a lot of space is lost to the left and right of the district.

The function mf_export() allows exports of maps whose height/width ratio is controlled and corresponds to that of a spatial object.

mf_export(dist_filter, "img/dist_filter_2.png", width = 480)
mf_map(dist_filter)
mf_title("Filtered district")
dev.off()

The extent of this map is exactly that of the displayed region.

5.2.14 Adding an image to a map

This can be useful for adding a logo, a pictograph. The function readPNG() of package png allows the additional images on the figure.

mf_theme("default", mar = c(0,0,0,0))
library(png)

logo <- readPNG("img/ird_logo.png")       #Import image
pp <- dim(logo)[2:1]*200                           #Image dimension in map unit (width and height of the original image)

#The upper left corner of the department's bounding box
xy <- st_bbox(district)[c(1,4)]
mf_map(district, col = "#D1914D", border = "white")
rasterImage(
  image   = logo,
  xleft   = xy[1] ,
  ybottom = xy[2] - pp[2],
  xright  = xy[1] + pp[1],
  ytop    = xy[2]
)

5.2.15 Place an item precisely on the map

The function locator() allows clicking on the figure and obtaining the coordinate of a point in the coordinate system of the figure (of the map).

# locator(1)                                      # click to get coordinate on map
# points(locator(1))                              # click to plot point on map
# text(locator(1),                                # click to place the item on map
#      labels ="Located any texts on map",        
#      adj = c(0,0))

locator()peut être utilisée sur la plupart des graphiques (pas ceux produits avec ggplot2).

5.2.16 Add shading to a layer

The function mf_shadow() allows to create a shadow to a layer of polygons.

mf_shadow(district)
mf_map(district, add=TRUE)

5.2.17 Creating Boxes

The function mf_inset_on() allows to start creation a box. You must then “close” the box with mf_inset_off().

mf_init(x = dist_selected, theme = "agolalight", expandBB = c(0,.1,0,.5)) 
mf_map(district, add = TRUE)
mf_map(dist_selected, col = "tomato4", border = "tomato1", lwd = 2, add = TRUE)

# Cambodia inset box
mf_inset_on(x = country, pos = "topright", cex = .3)
mf_map(country, lwd = .5, border= "grey90")
mf_map(dist_selected, col = "tomato4", border = "tomato1", lwd = .5, add = TRUE)
mf_scale(size = 100, pos = "bottomleft", cex = .6, lwd = .5)
mf_inset_off()

# District inset box
mf_inset_on(x = district, pos = "bottomright", cex = .3)
mf_map(district, lwd = 0.5, border= "grey90")
mf_map(dist_selected, col = "tomato4", border = "tomato1", lwd = .5, add = TRUE)
mf_scale(size = 100, pos = "bottomright", cex = .6, lwd = .5)
mf_inset_off()

# World inset box
mf_inset_on(x = "worldmap", pos = "topleft")
mf_worldmap(dist_selected, land_col = "#cccccc", border_col = NA, 
            water_col =  "#e3e3e3", col = "tomato4")

mf_inset_off()
mf_title("Bakan district and its surroundings")
mf_scale(10, pos = 'bottomleft')

5.3 3D maps

5.3.1 linemap

The package linemap (Giraud 2021) allows you to make maps made up of lines.

library(linemap)
library(mapsf)
library(sf)
library(dplyr)

pp = st_read("data_cambodia/PP.gpkg", quiet = TRUE)      # import Phnom Penh administrative border
pp_pop_dens <- getgrid(x = pp, cellsize =1000, var = "DENs")   # create population density in grid format  (pop density/1km)

mf_init(pp)

linemap(
  x = pp_pop_dens,  
  var = "DENs",
  k = 1,
  threshold = 5, 
  lwd = 1,
  col = "ivory1",
  border = "ivory4",
  add = T)

mf_title("Phnom Penh Population Density, 2019")
mf_credits("Humanitarian Data Exchange, 2022\nunit data:km2")

# url = "https://data.humdata.org/dataset/1803994d-6218-4b98-ac3a-30c7f85c6dbc/resource/f30b0f4b-1c40-45f3-986d-2820375ea8dd/download/health_facility.zip"
# health_facility.zip = "health_facility.zip"
# download.file(url, destfile = health_facility.zip)
# unzip(health_facility.zip) # Unzipped files are in a new folder named Health
# list.files(path="Health")

5.3.2 Relief Tanaka

We use the tanaka package (Giraud 2022b) which provides a method (Tanaka 1950) used to improve the perception of relief.

library(tanaka)
library(terra)

rpop <- rast("data_cambodia/khm_pd_2019_1km_utm.tif")     # Import population raster data (in UTM)
district = st_read("data_cambodia/cambodia.gpkg", layer = "district", quiet = TRUE)   # Import Cambodian districts layer
district <- st_transform(district, st_crs(rpop))    # Transform data into the same coordinate system

mat <- focalMat(x = rpop, d = c(1500), type = "Gauss")  # Raster smoothing
rpopl <- focal(x = rpop, w = mat, fun = sum, na.rm = TRUE)

# Mapping
cols <- hcl.colors(8, "Reds", alpha = 1, rev = T)[-1]
mf_theme("agolalight")
mf_init(district)
tanaka(x = rpop, breaks = c(0,10,25,50,100,250,500,64265),
       col = cols, add = T, mask = district, legend.pos = "n")
mf_legend(type = "choro", pos = "bottomright", 
          val = c(0,10,25,50,100,250,500,64265), pal = cols,
          bg = "#EDF4F5", fg = NA, frame = T, val_rnd = 0,
          title = "Population\nper km2")
mf_title("Population density of Cambodia, 2019")
mf_credits("Humanitarian Data Exchange, 2022",
           bg = "#EDF4F5")

5.4 Cartographic Transformation

classical anamorphosis is a representation of States(or any cells) by rectangle or any polygons according to a quantities attached to them. (…) We strive to keep the general arrangement of meshes or the silhouette of the continent.”
Brunet, Ferras, and Théry (1993)

3 types of anamorphoses or cartograms are presented here:

A comprehensive course on anamorphoses : Les anamorphoses cartographiques (Lambert 2015).

To make the cartograms we use the package cartogram (Jeworutzki 2020).

5.4.1 Dorling’s cartograms

The territories are represented by figures (circles, squares or rectangles) which do not overlap, the surface of which are proportional to a variable. The proportion of the figures are defined according to the starting positions.

Space is quite poorly identified.
You can name the circles to get your bearings and/or use the color to make clusters appear and better identify the geographical blocks.
The perception of quantities is very good. The circle sizes are really comarable.
library(mapsf)
library(cartogram)
district <- st_read("data_cambodia/cambodia.gpkg", layer = "district" , quiet = TRUE)
dist_dorling <- cartogram_dorling(x = district, weight = "T_POP", k = 0.7)
mf_map(dist_dorling, col = "#40E0D0", border= "white")
mf_label(
  x = dist_dorling[order(dist_dorling$T_POP, decreasing = TRUE), ][1:10,], 
  var = "ADM2_EN",
  overlap = FALSE, 
  # show.lines = FALSE,
  halo = TRUE, 
  r = 0.15
)
mf_title("Population of District - Dorling Cartogram")

The parameter k allows to vary the expansion factor of the circles.

5.4.2 Non-continuous cartograms

The size of the polygons is proportional to a variable. The arrangement of the polygons relative to each other is preserved. The shape of the polygons is similar.

(Cauvin, Escobar, and Serradj 2013)

The topology of the regions is lost.
The converstion of the polygons shape is optimal.
dist_ncont <- cartogram_ncont(x = district, weight = "T_POP", k = 1.2)
mf_map(district, col = NA, border = "#FDFEFE", lwd = 1.5)
mf_map(dist_ncont, col = "#20B2AA", border= "white", add = TRUE)
mf_title("Population of District - Non-continuous cartograms")

The parameter k allows to vary the expansion of the polygons.

5.4.3 Continuous cartograms

The size of the polygons is proportional to variable. The arrangement of the polygons relative to each other is preserved. To maintain contiguity, the sape of the polygons is heavily transformed.

(Paull and Hennig 2016)

The shape of the polygond is strongly distorted.

It is a “real geographical map”: topology and contiguity are preserved.

dist_ncont <- cartogram_cont(x = district, weight = "DENs", maxSizeError = 6)
Mean size error for iteration 1: 15.8686749410166
Mean size error for iteration 2: 12.1107731631101
Mean size error for iteration 3: 9.98940057337996
Mean size error for iteration 4: 8.62323208787643
Mean size error for iteration 5: 7.60706404894655
Mean size error for iteration 6: 6.83561617758241
Mean size error for iteration 7: 10.1399490743501
Mean size error for iteration 8: 5.79418495291592
mf_map(dist_ncont, col = "#66CDAA", border= "white", add = FALSE)
mf_title("Population of District - Continuous cartograms")
mf_inset_on(district, cex = .2, pos = "bottomleft")
mf_map(district, lwd = .5)
mf_inset_off()

5.4.4 Stengths and weaknessses of cartograms

cartograms are cartographic representations perceived as innovative (although the method is 40 years old). These very generalize images capture quantities and gradients well. These are real communication images that provoke, arouse interest, convey a strong message, challenge.

But cartograms induce a loss of visual cues (difficult to find one’s country or region on the map), require a reading effort which can be significant and do not make it possible to manage missing data.