早些时候我发布了一个关于使用ggplot和地图HERE在地图上绘制县名的问题。我的第一种方法是采用每个县的所有纬度和长坐标的方法,如下所示:
值得庆幸的是,Andrie提出了两个建议,即使用范围中心改善居中,然后是coord_map(){这似乎可以保持宽高比正确}。这在很大程度上改善了中心位置,如下所示:
我认为这看起来更好,但在重叠问题上仍有一些困难。我希望进一步提高中心性(在同一个线程中Justin提出了一个kmeans方法)。如果有必要,我可以旋转文本,但我希望在必要时将它们居中并旋转(它们超出县界),以便在地图上最好地显示县名。
有什么想法吗?
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
p <- ggplot(ny, aes(long, lat, group=group)) + geom_polygon(colour='black', fill=NA)
#my first approach to centering
cnames <- aggregate(cbind(long, lat) ~ subregion, data=ny, FUN=mean)
ggplot(ny, aes(long, lat)) +
geom_polygon(aes(group=group), colour='black', fill=NA) +
geom_text(data=cnames, aes(long, lat, label = subregion), size=3)
#Andrie's much improved approach to centering
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=3) +
coord_map()
答案 0 :(得分:8)
正如我昨晚在Talk Stats(link)处理过的那样,如果你使用R空间包(<{3}}),它实际上很容易(作为我在凌晨花费的时间的产物!) EM>属)。我测试了一些其他函数来创建 SpatialPolygons 对象,您可以使用坐标来返回多边形质心。我只为一个县做过,但 Polygon (S4)对象的标签点与质心相匹配。假设这是真的,那么Polygon对象的标签点就是质心。我使用这个小过程来创建质心的数据框并使用它们在地图上绘图。
library(ggplot2) # For map_data. It's just a wrapper; should just use maps.
library(sp)
library(maps)
getLabelPoint <- # Returns a county-named list of label points
function(county) {Polygon(county[c('long', 'lat')])@labpt}
df <- map_data('county', 'new york') # NY region county data
centroids <- by(df, df$subregion, getLabelPoint) # Returns list
centroids <- do.call("rbind.data.frame", centroids) # Convert to Data Frame
names(centroids) <- c('long', 'lat') # Appropriate Header
map('county', 'new york')
text(centroids$long, centroids$lat, rownames(centroids), offset=0, cex=0.4)
这对每个多边形都不适用。通常,GIS中的标注和注释过程要求您为那些不适合您想要使用的自动(系统)方法的特殊情况调整标签和注释。我们对此采取的代码 - 重新编码方法并不恰当。最好包括检查给定绘图的给定大小的标签是否适合多边形;如果没有,请将其从文本标签的记录中删除,然后手动插入以适应这种情况 - 例如,在多边形的一侧添加一个引线和注释,或者像其他地方一样在侧面转动标签。
答案 1 :(得分:2)
这是一个非常有用的讨论。为了使与dplyr
一起成长的人受益,这是一个小调整,使用管道代替aggregate
:
library(maps); library(dplyr); library(ggplot2)
ny <- map_data('county', 'new york')
cnames1 <- aggregate(cbind(long, lat) ~ subregion, data=ny,
FUN=function(x)mean(range(x)))
cnames2 <- ny %>% group_by(subregion) %>%
summarize_at(vars(long, lat), ~ mean(range(.)))
all.equal(cnames1, as.data.frame(cnames2))
答案 2 :(得分:1)
我认为这个问题最简单的答案是Andrie已经解决了大部分手工问题。其余的需要完成一些好的调整和看法。当你在Andrie的建议之后看一下情节时,除了一些可以通过纬度/经度变化或旋转进行改善的讨厌的放置外,大部分都是不错的。我有一个萨福克(右下角)和herkimer(中心)的例子,因为萨福克的位置可以通过拉/长调整和herkimer通过旋转来改善。
在:
cnames <- aggregate(cbind(long, lat) ~ subregion, data=ny,
FUN=function(x)mean(range(x))) #Andrie's code
cnames[52, 2:3] <- c(-73, 40.855) #adjust the long and lat of poorly centered names
cnames$angle <- rep(0, nrow(cnames)) #create an angle column
cnames[22, 4] <- -90 #adjust the angle of atypically shaped
ggplot(ny, aes(long, lat)) +
geom_polygon(aes(group=group), colour='black', fill=NA) +
geom_text(data=cnames, aes(long, lat, label = subregion, colour=col,
angle=angle), size=3) + coord_map()
这给了我们:
除非有人有更好的方法,否则我会将此答案标记为正确。
答案 3 :(得分:0)
您可以查看directlabels
包,它使用许多避免重叠的算法提供自动标签放置。我不确定它是否可用于解决您的问题,但您可以看看。
答案 4 :(得分:0)
有PAL labeling library似乎可以自动完成您正在寻找的内容。此截图来自他们的网站:
我还没有找到它的R接口。 quick guide to perform your own integration of PAL within your favourite GIS application表明集成本身应该是可行的。但是,在ggplot2上下文中,这意味着必须在渲染期间执行标签放置 - 我不知道这是否可行或者如何实现此目的。