在R ggplot中对地图多边形进行标注

16

我正在尝试使用R语言的ggplot给我的多边形打标签。我在stackoverflow上找到一个非常接近我想要的帖子,只是它是关于点的。

在geom_point中标记点

我在网上找到了一些方法。现在首先需要找到每个形状的中心位置,然后将这些位置和名称放在一起。然后将其与geom_text()中的标签函数链接起来。

ggplot地图上的居中名称

由于我已经尝试了很长时间,所以我决定提出问题,希望这里有人可以给我最终推动我所需的事情。我的绘图函数:

region_of_interest.fort <- fortify(region_of_interest, region = "score")
region_of_interest.fort$id <- as.numeric(region_of_interest.fort$id)
region_of_interest.fort$id <- region_of_interest.fort$id


region_of_interest.fort1 <- fortify(region_of_interest, region = "GM_NAAM")
region_of_interest.fort1$id <- as.character(region_of_interest.fort1$id)
region_of_interest.fort1$id <- region_of_interest.fort1$id

idList <- unique(region_of_interest.fort1$id)
centroids.df <- as.data.frame(coordinates(region_of_interest))
names(centroids.df) <- c("Longitude", "Latitude")
randomMap.df <- data.frame(id = idList, shading = runif(length(idList)), centroids.df)

ggplot(data = region_of_interest.fort, aes(x = long, y = lat, fill = id, group = group)) +
  geom_polygon() +
  geom_text(centroids.df, aes(label = id, x = Longitude, y = Latitude)) +
  scale_fill_gradient(high = "green", low = "red", guide = "colorbar") +
  coord_equal() +
  theme() +
  ggtitle("Title")

我在使用ggplot2时遇到了错误:ggplot2不知道如何处理类别为uneval的数据。

我的数据

region_of_interest$GM_NAAM
 [1] Groningen        Haren            Ooststellingwerf Assen            Aa en Hunze      Borger-    Odoorn   
 [7] Noordenveld      Westerveld       Tynaarlo         Midden-Drenthe  
415 Levels: 's-Gravenhage 's-Hertogenbosch Aa en Hunze Aalburg Aalsmeer Aalten ... Zwolle

region_of_interest$score
 [1] 10 -2 -1  2 -1 -4 -4 -5  0  0

为了回答您的问题,提供您使用的数据示例将非常有用。您可以在此处获取更多信息:https://dev59.com/eG025IYBdhLWcg3whGSx - Pop
我很感激您的评论。对于我这样一个R初学者来说,您提供的链接页面看起来非常困难。但是我认为我的问题相当清晰,肯定有人已经做过了。如果我排除标签,该函数可以绘制图形。您可以想象空形状,形状或数据并不重要。现在我想在其中放置一个标签。 - Zuenie
这个例子做你想要的事情。 - jlhoward
2个回答

21

尝试像这样做:

  1. 从原始地图对象中获取多边形质心的数据框。

  2. 在您要绘制的数据框中,确保有要标记的ID以及这些质心的经度和纬度的列。

  3. 使用ggplot中的geom_text添加标签。

根据此示例我读取了世界地图,提取ISO3 ID用作我的多边形标签,并创建了一个包含国家ID、人口以及质心的经度和纬度的数据框。然后,在世界地图上绘制人口数据并在质心处添加标签。

library(rgdal) # used to read world map data
library(rgeos) # to fortify without needing gpclib
library(maptools)
library(ggplot2)
library(scales) # for formatting ggplot scales with commas

# Data from http://thematicmapping.org/downloads/world_borders.php.
# Direct link: http://thematicmapping.org/downloads/TM_WORLD_BORDERS_SIMPL-0.3.zip
# Unpack and put the files in a dir 'data'

worldMap <- readOGR(dsn="data", layer="TM_WORLD_BORDERS_SIMPL-0.3")
# Change "data" to your path in the above!
worldMap.fort <- fortify(world.map, region = "ISO3")
# Fortifying a map makes the data frame ggplot uses to draw the map outlines.
# "region" or "id" identifies those polygons, and links them to your data. 
# Look at head(worldMap@data) to see other choices for id.
# Your data frame needs a column with matching ids to set as the map_id aesthetic in ggplot. 
idList <- worldMap@data$ISO3
# "coordinates" extracts centroids of the polygons, in the order listed at worldMap@data
centroids.df <- as.data.frame(coordinates(worldMap))
names(centroids.df) <- c("Longitude", "Latitude")  #more sensible column names
# This shapefile contained population data, let's plot it.
popList <- worldMap@data$POP2005

pop.df <- data.frame(id = idList, population = popList, centroids.df)

ggplot(pop.df, aes(map_id = id)) + #"id" is col in your df, not in the map object 
  geom_map(aes(fill = population), colour= "grey", map = worldMap.fort) +
  expand_limits(x = worldMap.fort$long, y = worldMap.fort$lat) +
  scale_fill_gradient(high = "red", low = "white", guide = "colorbar", labels = comma) +
  geom_text(aes(label = id, x = Longitude, y = Latitude)) + #add labels at centroids
  coord_equal(xlim = c(-90,-30), ylim = c(-60, 20)) + #let's view South America
  labs(x = "Longitude", y = "Latitude", title = "World Population") +
  theme_bw() 

Population map of South America

小技巧提示:实际上,sp包中的coordinates并不能完全找到质心,但通常可以给出标签的合理位置。如果您想在更复杂的情况下(如非连续形状)在真正的质心处标记,请使用rgeos包中的gCentroid


谢谢您的评论。我正在尝试使用您的脚本,它对我来说似乎非常合理,我只需要让它正常工作。 - Zuenie
在实现您的代码后,我已经调整了原始问题。我认为我遇到了您在评论中提到的问题。 - Zuenie
解决方案不是从加固的DF中读取ID,也不是从原始地图中读取质心。相反,请使用上面代码中的@data。希望这可以帮助到您。 - Silverfish
非常感谢您一直以来的帮助!我已经明白了,而且它很漂亮! - Zuenie
如果您正在使用ggplot制作氯丙图,您可能还会对以下内容感兴趣:https://dev59.com/82w15IYBdhLWcg3wQpXS#14168083 - Silverfish

3

这里接受的答案可能有效,但实际上所问的问题特别指出了存在一个错误:“ggplot2不知道如何处理类uneval的数据。”

它给出错误的原因是因为centroids.df的包含需要是一个命名变量(例如,伴随着“data=”)

当前:

ggplot(data = region_of_interest.fort, aes(x = long, y = lat, fill = id, group = group)) +
  geom_polygon() +
  geom_text(centroids.df, aes(label = id, x = Longitude, y = Latitude)) +
  scale_fill_gradient(high = "green", low = "red", guide = "colorbar") +
  coord_equal() +
  theme() +
  ggtitle("Title")

应该这样写(注意:“data=centroids.df”):
ggplot(data = region_of_interest.fort, aes(x = long, y = lat, fill = id, group = group)) +
  geom_polygon() +
  geom_text(data=centroids.df, aes(label = id, x = Longitude, y = Latitude)) +
  scale_fill_gradient(high = "green", low = "red", guide = "colorbar") +
  coord_equal() +
  theme() +
  ggtitle("Title")

这个问题的解决方法在这里:如何处理 ggplot2 中的 "data of class uneval" 错误?

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接