在地理地图上标出我们患者的出处

Plotting on a geographical map the provenience of our patients

我正试图在意大利地理地图上放一个点来报告我们患者的出处 ('provincia')。理想情况下,点的大小应与来自该 'provincia' 的患者数量成正比。我想绘制的列表示例如下。

MI  8319
CO  537
MB  436
VA  338
BG  310
PV  254
CR  244
NO  210
RM  189
CS  179

第一列中有 'provincia' 代码:MI(米兰)、CO(科莫)、MB(蒙扎-布里安扎)等。第二列中有患者人数'provincia'。所以输出应该是意大利政治地图,其中最大的点在米兰市 (MI) 周围,第二大点在科莫市 (CO) 附近,第三个点在蒙扎-布里安扎市 (MB) 附近),ETC。 是否有任何软件包可以完成我正在寻找的情节?我在这里找到了一个可以完成这项工作的工具,但显然他们希望我加载地理坐标才能完成绘图。

https://www.littlemissdata.com/blog/maps

提前致谢。

这是处理您的任务的一种方法。你有意大利省份的缩写。您希望使用它们将您的数据与多边形数据合并。如果您从 GADM 下载意大利的多边形,您可以获得包含缩写的数据。具体来说,HASC_2 列就是其中之一。您需要将数据与多边形数据合并。然后,您想要创建另一个包含质心的数据集。你可以用这两个数据集绘制地图。

library(tidyverse)
library(sf)
library(ggthemes)

# Get the sf file from https://gadm.org/download_country_v3.html
# and import it in R.

mysf <- readRDS("gadm36_ITA_2_sf.rds")

# This is your data, which is called mydata.
mydata <- structure(list(abbs = c("MI", "CO", "MB", "VA", "BG", "PV", "CR", 
"NO", "RM", "CS"), value = c(8319L, 537L, 436L, 338L, 310L, 254L, 
244L, 210L, 189L, 179L)), class = "data.frame", row.names = c(NA, 
-10L))

   abbs value
1    MI  8319
2    CO   537
3    MB   436
4    VA   338
5    BG   310
6    PV   254
7    CR   244
8    NO   210
9    RM   189
10   CS   179

# Abbreviations are in HASC_2 in mysf. Manipulate strings so that
# I can join mydata with mysf with the abbreviations. I also get
# longitude and latitude with st_centroid(). This data set is for
# geom_point().

mysf2 <- mutate(mysf, HASC_2 = sub(x = HASC_2, pattern = "^IT.", replacement = "")) %>% 
         left_join(mydata, by = c("HASC_2" = "abbs")) %>% 
         mutate(lon = map_dbl(geometry, ~st_centroid(.x)[[1]]),
                lat = map_dbl(geometry, ~st_centroid(.x)[[2]]))

# Draw a map

ggplot() +
geom_sf(data = mysf) +
geom_point(data = mysf2, aes(x = lon, y = lat, size = value)) +
theme_map()

插图更新

这是根据关于使用插图的不同建议进行的更新,我认为这将是您问题和评论的最佳解决方案:

library(sf)
library(cartography)


EU = st_read("~/R/mapslib/EUROSTAT/NUTS_RG_03M_2016_3035_LEVL_3.geojson")
IT = subset(EU, CNTR_CODE == "IT")
mydata <-
  structure(list(
    abbs = c("MI", "CO", "MB", "VA", "BG", "PV", "CR",
             "NO", "RM", "CS"),
    value = c(8319L, 537L, 436L, 338L, 310L, 254L,
              244L, 210L, 189L, 179L),
    nuts = c("ITC4C","ITC42","ITC4D","ITC41",
             "ITC46", "ITC48","ITC4A","ITC15",
             "ITI43","ITF61")
  ),
  class = "data.frame",
  row.names = c(NA, -10L))

patients = merge(IT, mydata, by.x = "id", by.y = "nuts")

#Get breaks for map
br=getBreaks(patients$value)
#Delimit zone
#Based on NUTS1, Nortwest Italy
par(mar=c(0,0,0,0))
ghostLayer(IT[grep("ITC",IT$NUTS_ID),], bg="lightblue")
plot(st_geometry(EU), col="grey90", add=TRUE)
plot(st_geometry(IT), col = "#FEFEE9", border = "#646464", add=TRUE)
choroLayer(
  patients,
  var = "value",
  breaks = br,
  col = carto.pal(pal1 = "red.pal", n1 = length(br)-1),
  legend.pos = "topleft",
  legend.title.txt = "Total patients",
  add = TRUE,
  legend.frame = TRUE
)
labelLayer(patients,txt="abbs", halo=TRUE, overlap = FALSE)

#Inset
par(
  fig = c(0, 0.4, 0.01, 0.4),
  new = TRUE
)
inset=patients[patients$abbs %in% c("RM","CS"),]
ghostLayer(inset, bg="lightblue")
plot(st_geometry(EU), col="grey90", add=TRUE)
plot(st_geometry(IT), col = "#FEFEE9", border = "#646464", add=TRUE)
choroLayer(
  patients,
  var = "value",
  breaks = br,
  col = carto.pal(pal1 = "red.pal", n1 = length(br)-1),
  legend.pos = "n",
  add = TRUE
)
labelLayer(patients,txt="abbs", halo=TRUE, overlap = FALSE)
box(which = "figure", lwd = 1)

#RESTORE PLOT

par(fig=c(0,1,0,1))

旧答案

根据我对绘制标签的评论,考虑到浓度,使用圆圈可能不是您地图的最佳选择。我建议你为此使用另一种地图,作为 chorolayer,我利用 https://whosebug.com/users/3304471/jazzurro 作为 dataframe

    library(sf)
    library(cartography)

    EU = st_read("~/R/mapslib/EUROSTAT/NUTS_RG_03M_2016_3035_LEVL_3.geojson")
    IT = subset(EU, CNTR_CODE == "IT")
    mydata <-
      structure(list(
        abbs = c("MI", "CO", "MB", "VA", "BG", "PV", "CR",
                 "NO", "RM", "CS"),
        value = c(8319L, 537L, 436L, 338L, 310L, 254L,
                  244L, 210L, 189L, 179L),
        nuts = c("ITC4C","ITC42","ITC4D","ITC41",
                 "ITC46", "ITC48","ITC4A","ITC15",
                 "ITI43","ITF61")
      ),
      class = "data.frame",
      row.names = c(NA, -10L))

    patients = merge(IT, mydata, by.x = "id", by.y = "nuts")

    #Options1 - With circles
    par(mar = c(0, 0, 0, 0))
    plot(st_geometry(IT), col = "#FEFEE9", border = "#646464")
    propSymbolsLayer(
      x = patients,
      var = "value",
      col = carto.pal(pal1 = "red.pal", n1 = 6),
      legend.title.txt = "Total patients",
      add = TRUE
    )

    #Option 2 - Chorolayer with labels
    par(mar = c(0, 0, 0, 0))
    plot(st_geometry(IT), col = "#FEFEE9", border = "#646464")
    choroLayer(
      patients,
      var = "value",
      col = carto.pal(pal1 = "red.pal", n1 = 6),
      legend.title.txt = "Total patients",
      add = TRUE
    )
    #Create labels
    patients$label = paste(patients$abbs, patients$value, sep = " - ")
    labelLayer(
      patients,
      txt = "label",
      overlap = FALSE,
      halo = TRUE,
      show.lines = TRUE,
      )

数据来自 https://ec.europa.eu/eurostat/cache/GISCO/distribution/v2/nuts/nuts-2016-files.html