ggplot центрированные имена на карте - PullRequest
14 голосов
/ 25 февраля 2012

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

Ответы [ 3 ]

25 голосов
/ 25 февраля 2012

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

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

4 голосов
/ 18 мая 2015

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

В пакете карт есть функция 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
0 голосов
/ 25 февраля 2012

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