关于 r:ggplot 在地图上居中名称

ggplot centered names on a map

我正在尝试使用 ggplot2 和地图来绘制纽约state的县名。我的方法是按县查找经纬度的平均值(我假设这是县的中心,但这可能是错误的想法),然后使用 geom_text 在地图上绘制名称。它的行为不像我预期的那样,因为它在每个县绘制了多个名称。

我正在寻找的结果是每个文本(县)的中心位于它各自县的中心。

除了解决问题之外,我希望能帮助理解我对 ggplot 的想法有什么问题。

提前谢谢你。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
library(ggplot2); library(maps)

county_df <- map_data('county')  #mappings of counties by state
ny <- subset(county_df, region=="new york")   #subset just for NYS
ny$county <- ny$subregion
cnames <- aggregate(cbind(long, lat) ~ subregion, data=ny, FUN=mean)

p <- ggplot(ny, aes(long, lat, group=group)) +  geom_polygon(colour='black', fill=NA)
p #p of course plots as expected

#now add some county names (3 wrong attempts)
p + geom_text(aes(long, lat, data = cnames, label = subregion, size=.5)) #not correct

#I said maybe I'm confusing it with the same names for different data sets
names(cnames) <-c('sr', 'Lo', 'La')
p + geom_text(Lo, La, data = cnames, label = sr, aes(size=.5)) #attempt 2
p + geom_text(aes(Lo, La, data = cnames, label = sr, size=.5)) #attempt 3

由于您要创建两个图层(一个用于多边形,第二个用于标签),您需要为每个图层正确指定数据源和映射:

1
2
3
ggplot(ny, aes(long, lat)) +  
    geom_polygon(aes(group=group), colour='black', fill=NA) +
    geom_text(data=cnames, aes(long, lat, label = subregion), size=2)

注意:

  • 由于 longlat 出现在两个数据帧中,您可以在第一次调用 ggplot 时使用 aes(long, lat)。您在此处声明的任何映射都可用于所有层。
  • 出于同样的原因,您需要在多边形层内声明 aes(group=group)
  • 在文本层中,您需要将数据源移到 aes 之外。

一旦你这样做了,并且地图绘制出来了,你会发现中点更接近于 range 的平均值,并使用尊重纵横比和投影的地图坐标系:

1
2
3
4
5
6
7
cnames <- aggregate(cbind(long, lat) ~ subregion, data=ny,
                    FUN=function(x)mean(range(x)))

ggplot(ny, aes(long, lat)) +  
    geom_polygon(aes(group=group), colour='black', fill=NA) +
    geom_text(data=cnames, aes(long, lat, label = subregion), size=2) +
    coord_map()

enter


我知道这是一个已经回答的老问题,但我想补充一下,以防有人在这里寻求未来的帮助。

地图包有 map.text 功能,它使用多边形质心来放置标签。查看它的代码,可以看到它使用 apply.polygoncentroid.polygon 函数来查找质心。这些函数在加载包时不可见,但仍然可以访问:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
library(ggplot2); library(maps)

county_df <- map_data('county')  #mappings of counties by state
ny <- subset(county_df, region=="new york")   #subset just for NYS
ny$county <- ny$subregion
cnames <- aggregate(cbind(long, lat) ~ subregion, data=ny, FUN=mean)

# Use the map function to get the polygon data, then find the centroids
county_poly <- map("county","new york", plot=FALSE, fill = TRUE)
county_centroids <- maps:::apply.polygon(county_poly, maps:::centroid.polygon)

# Create a data frame for graphing out of the centroids of each polygon
# with a non-missing name, since these are the major county polygons.
county_centroids <- county_centroids[!is.na(names(county_centroids))]
centroid_array <- Reduce(rbind, county_centroids)
dimnames(centroid_array) <- list(gsub("[^,]*,","", names(county_centroids)),
                                 c("long","lat"))
label_df <- as.data.frame(centroid_array)
label_df$county <- rownames(label_df)

p <- ggplot(ny, aes(long, lat, group=group)) + geom_polygon(colour='black', fill=NA)

plabels <- geom_text(data=label_df, aes(label=county, group=county))
p + plabels


@tjebo 在我尝试创建一个新的统计数据时向我指出,这个统计数据将是这个问题的合适解决方案。 它不在 CRAN 上(还),但生活在 github 上。(免责声明:我写了 ggh4x)

对于处理类似问题的其他人,这是如何工作的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
library(ggh4x)
#> Loading required package: ggplot2
#> Warning: package 'ggplot2' was built under R version 4.0.2
library(maps)

county_df <- map_data('county')
ny <- subset(county_df, region=="new york")
ny$county <- ny$subregion


ggplot(ny, aes(x = long, y = lat, group = group)) +  
  geom_polygon(colour='black', fill=NA) +
  stat_midpoint(aes(label = subregion), geom ="text",size=3) +
  coord_map()

></p>
<p>由 reprex 包 (v0.3.0) 创建于 2020-07-06</p>
<hr>
<p>似乎kmeans中心会很有用...这是一个糟糕的开始...为时已晚!</p>
<div class=

1
2
3
center.points <- ddply(ny, .(group), function(df) kmeans(df[,1:2], centers=1)$centers)    
center.points$county <- ny$county[ny$group == center.points$group]
p + geom_text(data=center.points, aes(x=V1, y=V2, label=county))