ggplot centrato su una mappa

Sto tentando di utilizzare ggplot2 e mappe per tracciare i nomi delle contee nello stato di New York. Il mio approccio era quello di trovare i mezzi di latitudine e longitudine per contea (presumo che questo sia il centro della contea, ma questo potrebbe essere un pensiero errato) e quindi usare geom_text per tracciare i nomi sulla mappa. Non si sta comportando come previsto, poiché sta tracciando più nomi per contea.

Il risultato che sto cercando è che il centro di ogni testo (contea) sia al centro della rispettiva contea.

Oltre a risolvere il problema, mi farebbe piacere aiutarti a capire cosa c’è di sbagliato nel mio modo di pensare con ggplot.

Grazie in anticipo.

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 

Poiché stai creando due livelli (uno per i poligoni e il secondo per le etichette), devi specificare l’origine dati e mappare correttamente per ogni livello:

 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) 

Nota:

  • Poiché long e lat verificano in entrambi i frame di dati, puoi utilizzare aes(long, lat) nella prima chiamata a ggplot. Qualsiasi mapping che dichiari qui è disponibile per tutti i livelli.
  • Per lo stesso motivo, devi dichiarare aes(group=group) all’interno del layer poligono.
  • Nel livello di testo, è necessario spostare l’origine dati all’esterno dei aes .

Una volta che hai fatto questo, e la mappa traccia, ti renderai conto che il punto medio è meglio approssimato dalla media della range , e di usare un sistema di coordinate della mappa che rispetti le proporzioni e la proiezione:

 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() 

inserisci la descrizione dell'immagine qui

So che questa è una vecchia domanda a cui è stata data una risposta, ma volevo aggiungere questo nel caso in cui qualcuno guardasse qui per un aiuto futuro.

Il pacchetto mappe ha la funzione map.text , che usa i centroidi del poligono per posizionare le etichette. Guardando il suo codice, si può vedere che usa le funzioni apply.polygon e centroid.polygon per trovare i centroidi. Queste funzioni non sono visibili quando il pacchetto è caricato, ma è ancora ansible accedervi:

 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 

Sembrerebbe che i centri di kmea sarebbero utili … Ecco un inizio scarso … è tardi!

 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))