Подтвердить что ты не робот

Ggplot с центрированными именами на карте

Я пытаюсь использовать 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
4b9b3361

Ответ 1

Поскольку вы создаете два слоя (один для полигонов и второй для меток), вам нужно правильно указать источник данных и правильное отображение для каждого слоя:

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)

Примечание:

  • Так как long и lat происходят в обоих кадрах данных, вы можете использовать aes(long, lat) в первом вызове ggplot. Любое отображение, которое вы объявляете здесь, доступно для всех слоев.
  • По той же причине вам нужно объявить 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

Ответ 2

Я знаю, что это старый вопрос, на который был дан ответ, но я хотел добавить это на тот случай, если кто-нибудь будет искать помощь в будущем.

Пакет карт имеет функцию map.text, в которой для размещения меток используются центрифуги полигонов. Посмотрев на его код, можно увидеть, что он использует функции apply.polygon и centroid.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

Ответ 3

Это похоже на то, что центры 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))