2012-02-25 11 views
12

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.ggplot Nomi centrati su una mappa

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

Oltre a risolvere il problema, mi piacerebbe molto aiutare 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 

risposta

24

Dal momento che si sta creando due strati (uno per i poligoni e la seconda per le etichette), è necessario specificare correttamente la fonte dei dati e la mappatura per ogni strato:

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:

  • Dal long e lat si verificano in entrambi i frame di dati, è possibile utilizzare aes(long, lat) nella prima chiamata a ggplot. Qualsiasi mappatura che dichiari qui è disponibile per tutti i livelli.
  • Per lo stesso motivo, è necessario dichiarare aes(group=group) all'interno del livello poligono.
  • Nel livello testo, è necessario spostare l'origine dati all'esterno di aes.

Una volta fatto questo, e la mappa trame, vi renderete conto che il punto centrale sia meglio approssimata dalla media di range, e di utilizzare un sistema di mappa che rispetta le proporzioni e la proiezione di coordinate:

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

+0

Penso che tu abbia fatto quello che ho chiesto e altro ancora. Quindi sto marcando questo thread come risolto. Grazie. Non sono ancora soddisfatto del posizionamento dei nomi e ora mi rendo conto che ho bisogno di un approccio migliore al centraggio. L'approccio di Justin sembra interessante. Inserirò un'altra domanda su alcune tecniche di centraggio migliorate. –

+0

Ancora meglio per il punto medio è la funzione centroide nel pacchetto geosfera. Ecco cosa ho fatto invece della funzione di aggregazione in questa risposta: 'cnames <- ddply (ia_pop,.(County, group), riepilogare, Centroid = centroid (cbind (long, lat))) e quindi suddividere la colonna Centroid in questo modo: 'cnames $ long <- cnames $ Centroid [, 1]' e 'cnames $ lat <- cnames $ Centroid [, 2]' – Danny

0

Sembra sorta come Kmeans centri sarebbe utile ... Qui è un inizio povero ... la sua fine!

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

Non guardarlo ... è orribile! – Justin

4

so che questa è una vecchia questione che è stata data risposta, ma ho voluto aggiungere questo nel caso qualcuno si presenta qui per aiuto futuro.

Il pacchetto mappe ha la funzione map.text, che utilizza 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 accessibile:

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

Sarebbe leggermente più utile se il codice includesse la riga per quello che 'p' è. Inoltre sto ricevendo un errore quando tenta di aggiungere 'p + plafels':' Errore in eval (expr, envir, enclos): oggetto 'gruppo' non trovato' –

+1

@ henry-e Modifiche apportate, anche se in ritardo sul mio parte. –