使用 tmap 和 sf 循环记录一系列地图

Posted

技术标签:

【中文标题】使用 tmap 和 sf 循环记录一系列地图【英文标题】:Records a series of maps with a loop using tmap and sf 【发布时间】:2021-11-14 22:51:04 【问题描述】:

我想使用 R 中的 sf 和 tmap 包记录一系列地图。我的数据是一个 sf 对象,具有链接到方形多边形的不同属性。对于我要映射的每个属性,映射的中断都是相同的,这就是我想编写一个简单循环的原因。

下面的代码将为您提供我的数据示例。抱歉,dput 有点长,因为 sf 对象集成了几何。

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")))

要使用 tmap 做地图,我在第一列使用以下代码:

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

它给了我想要的东西

在示例数据中,共有三列。所以我写了这个简单的循环来为每一列使用相同的中断做一系列映射。

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()

此循环不起作用,我的文件夹中的文件已创建但为空。此外,将所有三个地图都放在一个文件上可能会更好,但我想先解决这个问题。非常感谢任何帮助。

【问题讨论】:

【参考方案1】:

您只需运行以下代码行,它应该可以工作。

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 = ""))


由reprex package (v2.0.1) 于 2021 年 9 月 21 日创建

【讨论】:

@ePoQ 如果您正在寻找,请验证答案,以便其他用户更容易找到正确的答案 @ePoQ 非常感谢您验证答案。这将是对其他用户有用的帮助。【参考方案2】:

只需在循环中使用print(m)

如果您想使用基本图形设备,您需要显式打印您的 tmap。否则,请像在其他答案中一样使用 tmap_save()

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

【讨论】:

以上是关于使用 tmap 和 sf 循环记录一系列地图的主要内容,如果未能解决你的问题,请参考以下文章

tm_text 在 tmap 中产生重复的文本

在 R 中编辑 tmap 数据文件

如何使用 tmap 在 choropleth 地图中舍入整数中断

在地图 R tmap 中放大城市

数据可视化应用绘制空间地图(附R语言代码)

65 STM32F0系列 串口DMA循环接收实验记录