0

I would like to record a series of maps using the sf and tmap packages in R. My data is an sf object with different attributes linked to square polygons. The breaks for the maps are the same for each attribute that I want to map, that's why I thought of coding a simple loop.

The code below will give you a sample of my data. Sorry, the dput is a bit long, it's because sf objects integrate geometries.

library(sf)
library(tmap)
library(tmaptools)

Mesh <- structure(list(C1_shr_0304 = c(10.5263157894737, 9.30232558139535, 
5.63380281690141, 10.4972375690608, 8.98876404494382, 5.51181102362205, 
8.51063829787234, 8.15217391304348, 12.6168224299065), C2_shr_0304 = c(2.10526315789474, 
3.48837209302326, 1.40845070422535, 0.552486187845304, 1.68539325842697, 
1.5748031496063, 3.19148936170213, 1.08695652173913, 2.33644859813084
), C3_shr_0304 = c(14.7368421052632, 15.1162790697674, 16.9014084507042, 
9.39226519337017, 10.1123595505618, 11.8110236220472, 8.51063829787234, 
15.2173913043478, 12.1495327102804), geom = structure(list(structure(list(
    list(structure(c(544950.2102893, 544663.90075037, 544662.782562812, 
    544949.084933334, 544950.2102893, 3836419.17735834, 3836417.78717694, 
    3836648.81133503, 3836650.2015547, 3836419.17735834), .Dim = c(5L, 
    2L)))), class = c("XY", "MULTIPOLYGON", "sfg")), structure(list(
    list(structure(c(545236.519875821, 544950.2102893, 544949.084933334, 
    545235.387351436, 545236.519875821, 3836420.57642335, 3836419.17735834, 
    3836650.2015547, 3836651.60065824, 3836420.57642335), .Dim = c(5L, 
    2L)))), class = c("XY", "MULTIPOLYGON", "sfg")), structure(list(
    list(structure(c(545522.829510243, 545236.519875821, 545235.387351436, 
    545521.689817429, 545522.829510243, 3836421.984372, 3836420.57642335, 
    3836651.60065824, 3836653.00864566, 3836421.984372), .Dim = c(5L, 
    2L)))), class = c("XY", "MULTIPOLYGON", "sfg")), structure(list(
    list(structure(c(544949.084933334, 544662.782562812, 544661.664316089, 
    544947.959517824, 544949.084933334, 3836650.2015547, 3836648.81133503, 
    3836879.83557164, 3836881.22582958, 3836650.2015547), .Dim = c(5L, 
    2L)))), class = c("XY", "MULTIPOLYGON", "sfg")), structure(list(
    list(structure(c(545235.387351436, 544949.084933334, 544947.959517824, 
    545234.254767129, 545235.387351436, 3836651.60065824, 3836650.2015547, 
    3836881.22582958, 3836882.62497164, 3836651.60065824), .Dim = c(5L, 
    2L)))), class = c("XY", "MULTIPOLYGON", "sfg")), structure(list(
    list(structure(c(544947.959517824, 544661.664316089, 544660.546010205, 
    544946.834042773, 544947.959517824, 3836881.22582958, 3836879.83557164, 
    3837110.85988679, 3837112.25018299, 3836881.22582958), .Dim = c(5L, 
    2L)))), class = c("XY", "MULTIPOLYGON", "sfg")), structure(list(
    list(structure(c(545234.254767129, 544947.959517824, 544946.834042773, 
    545233.122122902, 545234.254767129, 3836882.62497164, 3836881.22582958, 
    3837112.25018299, 3837113.64936355, 3836882.62497164), .Dim = c(5L, 
    2L)))), class = c("XY", "MULTIPOLYGON", "sfg")), structure(list(
    list(structure(c(545521.689817429, 545235.387351436, 545234.254767129, 
    545520.550064315, 545521.689817429, 3836653.00864566, 3836651.60065824, 
    3836882.62497164, 3836884.03299782, 3836653.00864566), .Dim = c(5L, 
    2L)))), class = c("XY", "MULTIPOLYGON", "sfg")), structure(list(
    list(structure(c(545520.550064315, 545234.254767129, 545233.122122902, 
    545519.4102509, 545520.550064315, 3836884.03299782, 3836882.62497164, 
    3837113.64936355, 3837115.05742848, 3836884.03299782), .Dim = c(5L, 
    2L)))), class = c("XY", "MULTIPOLYGON", "sfg"))), n_empty = 0L, crs = structure(list(
    epsg = 6690L, proj4string = "+proj=utm +zone=53 +ellps=GRS80 +units=m +no_defs"), class = "crs"), class = c("sfc_MULTIPOLYGON", 
"sfc"), precision = 0, bbox = structure(c(xmin = 544660.546010205, 
ymin = 3836417.78717694, xmax = 545522.829510243, ymax = 3837115.05742848
), class = "bbox"))), row.names = c(NA, -9L), class = c("sf", 
"data.frame"), sf_column = "geom", agr = structure(c(C1_shr_0304 = NA_integer_, 
C2_shr_0304 = NA_integer_, C3_shr_0304 = NA_integer_), class = "factor", .Label = c("constant", 
"aggregate", "identity")))

To do a map with tmap, I use the following code for the first column :

tm_shape(Mesh) + 
  tm_fill(col = paste0(colnames(Mesh)[1]), breaks = c(0,2.5,5,7.5,10,100),
          palette= "-magma")

which give me what I want

enter image description here

In the sample data, there is three columns. So I wrote this simple loop to do a series of maps for each column using the same breaks.

for (i in 1:3){
  png(filename = paste0(colnames(Mesh)[i],".png"), width = 480, height = 480)
  tm_shape(Mesh) + 
  tm_fill(col = paste0(colnames(Mesh)[i]), breaks = c(0,2.5,5,7.5,10,100),
          palette= "-magma")
  dev.off()
}

This loop is not working, the files in my folder are created but empty. Also, having all the three maps on only one file could be even better, but I would like to solve this issue first. Any help greatly appreciated.

ePoQ
  • 434
  • 3
  • 18

2 Answers2

2

You just have to run the following lines of code and it should work.

library(tmap)

for (i in 1:3){

  res <- tm_shape(Mesh) + 
    tm_fill(col = paste0(colnames(Mesh)[i]), breaks = c(0,2.5,5,7.5,10,100),
            palette= "-magma")
  
  tmap_save(res, filename = paste0(colnames(Mesh)[i], ".png", sep = ""))

}

Created on 2021-09-21 by the reprex package (v2.0.1)

lovalery
  • 4,524
  • 3
  • 14
  • 28
  • 1
    @ePoQ If that is want you were looking for, please, validate the answer to make it easier for other users to find the right answers – lovalery Sep 21 '21 at 12:54
  • @ePoQ Thank you very much for validating the answer. It will be a useful help for other users. – lovalery Sep 21 '21 at 15:47
2

Just use print(m) in your loop.

If you want to use a base graphic device, you need to print your tmap explictly. Otherwise, use tmap_save() like in the other answer.

for(i in 1:3){
  png(filename = paste0(colnames(Mesh)[i],".png"), width = 480, height = 480)
  m <- tm_shape(Mesh) + 
    tm_fill(col = paste0(colnames(Mesh)[i]),
            breaks = c(0,2.5,5,7.5,10,100),
            palette= "-magma")
  print(m)
  dev.off()
}

why is tmap function within for loop that also has left join not working

Skaqqs
  • 4,010
  • 1
  • 7
  • 21