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
Ответы
Ответ 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))