以编程方式在ggplot映射的同一点添加多个文本标签

时间:2014-11-30 13:24:35

标签: r ggplot2 maps labels

我的挑战是在地图上的同一点周围添加几个文字标签。 MWE数据框架将六个运动队围绕纽约市。

library(maps) 
library(mapproj)
library(maptools)

all_states <- map_data("state") # load map outline and borders for US states
ny <- subset(all_states, region == "new york") # select only New York
nyteams <- c("Mets", "Yankees", "Knicks", "Giants", "Islanders", "Jets") # for text labels
df <- data.frame(long = rep(-73.99, times = 6), lat = rep(40.71, times =6)) # NYC coordinates for each team
df <- cbind(nyteams, df) # combine the columns to create the data frame for ggplot2
df <- cbind(df, rownum = seq(1:nrow(df))) # variable for spreading text labels by vertical latitude

通过增加每个点的纬度来垂直添加文本标签很简单。

df $ lat2&lt; - df $ lat +(0.1 * df $ rownum)#将文本标签分散到纬度

ggplot(data = df, aes(long, lat2)) + 
  geom_polygon(data = ny, aes(x=long, y=lat, group = group), colour="grey70", fill="white") +
  coord_map("mercator") + # did not include geom_point() since text labels are sufficient
  geom_text(aes(label = nyteams), size = 3)

但是我手动制定了一个系统,用于将第一支球队置于纽约市经度和经度,第二支球队位于其上方,第三支球队位于右侧,第四支球队位于其下方,第五支球队位于左下方(我可以缩短团队名称,以避免过度编写岛民,等等。

df$lat2 <- df$lat   + c(0, 0.1, 0.0, -0.1,  0.0, 0.2)
df$long2 <- df$long + c(0, 0.0, 0.3,  0.0, -0.5, 0.0)

ggplot(data = df, aes(long2, lat2)) + 
  geom_polygon(data = ny, aes(x=long, y=lat, group = group), colour="grey70", fill="white") +
  coord_map("mercator") + 
  geom_text(aes(label = nyteams), size = 3)

编程问题:R如何在没有太多人工干预的情况下创建多个文本标签位置?

我尝试了position =“jitter”和position =“dodge”无济于事。

关于SO的其他几个问题已经询问了如何向地图添加多个文本注释。限制困扰着他们所有人。

Can you plot a table onto a ggmap similar to annotation_custom method for non- Cartesian coordinates Dynamic position for ggplot2 objects (especially geom_text)? 但直接标签包不适用于各个点 https://stats.stackexchange.com/questions/16057/how-do-i-avoid-overlapping-labels-in-an-r-plot/62856#62856 FField包

1 个答案:

答案 0 :(得分:2)

这是一种“半”自动方法,它将标签放置在圆点周围。

ny.coords <- data.frame(long=-73.99, lat=40.71)
n <- length(nyteams)
r <- 0.3
th <- seq(0,2*(n-1)/n*pi,len=n)
coords <- data.frame(long=r*sin(th)+ny.coords$long,lat=r*cos(th)+ny.coords$lat)
ggplot(data=ny,aes(x=long,y=lat)) + 
  geom_polygon(data = ny, aes(group = group), colour="grey70", fill="white") +
  geom_text(data=coords,aes(label = nyteams), size = 3)+
  geom_point(data=ny.coords,color="red",size=3)+
  coord_map("mercator",xlim=c(-75,-73),ylim=c(40,41.5))

“半”位是我根据地图的比例选择了一个半径(r),但你也可以将其自动化。


编辑:对OP评论的回应。

这种方法中没有任何内容可以明确避免重叠。但是,改变行

th <- seq(0,2*(n-1)/n*pi,len=n)

th <- seq(0,2*(n-1)/n*pi,len=n) + pi/(2*n)

产生这个:

如果标签没有太多,

标签位置会旋转一点,并且(有时)可以避免重叠。

另外,您应该查看directlabels package