ggplot在地图上居中显示名称

时间:2012-02-25 05:06:31

标签: r ggplot2 geocoding

我正在尝试使用ggplot2和地图绘制纽约州的县名。我的方法是通过县找到纬度和经度的方法(我假设这是县的中心,但这可能是错误的思考),然后使用geom_text在地图上绘制名称。它没有像我预期的那样表现,因为它正在为每个县绘制多个名字。

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

除了解决问题之外,我还很高兴能帮助理解我对ggplot思考的问题。

提前谢谢。

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

4 个答案:

答案 0 :(得分:25)

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

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的平均值,并使用一个尊重纵横比和投影的地图坐标系:

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 image description here

答案 1 :(得分:4)

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

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

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

答案 2 :(得分:2)

pointed out to me by @tjebo,当时我正在尝试进行新的统计,该统计将是此问题的合适解决方案。它尚未在CRAN上,但仍在github上。

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

library(ggh4x) # devtools::install_github("teunbrand/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()

reprex package(v0.3.0)于2020-07-06创建

答案 3 :(得分:0)

有点像kmeans中心会很有用......这是一个糟糕的开始......它已经晚了!

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