tracciare grafici a torta sulla mappa in ggplot

Questa potrebbe essere una lista di desideri, non è sicuro (cioè forse ci sarebbe bisogno di essere la creazione di geom_pie perché ciò avvenga). Ho visto una mappa oggi ( LINK ) con grafici a torta su di esso come visto qui. inserisci la descrizione dell'immagine qui

Non voglio discutere i meriti di un grafico a torta, questo era più di un esercizio di posso farlo in ggplot?

Ho fornito un set di dati di seguito (caricato dalla mia casella di riepilogo) che contiene i dati di mapping per creare una mappa dello Stato di New York e alcuni dati puramente fabbricati sulle percentuali razziali per contea. Ho dato questo trucco razziale come fusione con il set di dati principale e come set di dati separato chiamato chiave. Penso anche che la risposta di Bryan Goodrich a me in un altro post ( QUI ) sui nomi di contea di centraggio sarà utile a questo concetto.

Come possiamo rendere la mappa sopra con ggplot2?

Un set di dati e la mappa senza i grafici a torta:

 load(url("http://dl.dropbox.com/u/61803503/nycounty.RData")) head(ny); head(key) #view the data set from my drop box library(ggplot2) ggplot(ny, aes(long, lat, group=group)) + geom_polygon(colour='black', fill=NA) # Now how can we plot a pie chart of race on each county # (sizing of the pie would also be controllable via a size # parameter like other `geom_` functions). 

Grazie in anticipo per le tue idee.

EDIT: Ho appena visto un altro caso a junkcharts che urla per questo tipo di funzionalità: inserisci la descrizione dell'immagine qui

Tre anni dopo questo è risolto. Ho messo insieme un certo numero di processi e grazie all’eccellente pacchetto ggtree di YuGuangchuang , questo può essere fatto abbastanza facilmente. Si noti che a partire da (9/3/2015) è necessario avere la versione 1.0.18 di ggtree installata, ma questi alla fine getteranno i rispettivi repository.

inserisci la descrizione dell'immagine qui

Ho usato le seguenti risorse per fare questo (i link daranno maggiori dettagli):

  1. blog ggtree
  2. sposta la legenda ggplot
  3. corretta versione di ggtree
  4. centrare le cose nei poligoni

Ecco il codice:

 load(url("http://dl.dropbox.com/u/61803503/nycounty.RData")) head(ny); head(key) #view the data set from my drop box if (!require("pacman")) install.packages("pacman") p_load(ggplot2, ggtree, dplyr, tidyr, sp, maps, pipeR, grid, XML, gtable) getLabelPoint <- function(county) {Polygon(county[c('long', 'lat')])@labpt} df <- map_data('county', 'new york') # NY region county data centroids <- by(df, df$subregion, getLabelPoint) # Returns list centroids <- do.call("rbind.data.frame", centroids) # Convert to Data Frame names(centroids) <- c('long', 'lat') # Appropriate Header pops <- "http://data.newsday.com/long-island/data/census/county-population-estimates-2012/" %>% readHTMLTable(which=1) %>% tbl_df() %>% select(1:2) %>% setNames(c("region", "population")) %>% mutate( population = {as.numeric(gsub("\\D", "", population))}, region = tolower(gsub("\\s+[Cc]ounty|\\.", "", region)), #weight = ((1 - (1/(1 + exp(population/sum(population)))))/11) weight = exp(population/sum(population)), weight = sqrt(weight/sum(weight))/3 ) race_data_long <- add_rownames(centroids, "region") %>>% left_join({distinct(select(ny, region:other))}) %>>% left_join(pops) %>>% (~ race_data) %>>% gather(race, prop, white:other) %>% split(., .$region) pies <- setNames(lapply(1:length(race_data_long), function(i){ ggplot(race_data_long[[i]], aes(x=1, prop, fill=race)) + geom_bar(stat="identity", width=1) + coord_polar(theta="y") + theme_tree() + xlab(NULL) + ylab(NULL) + theme_transparent() + theme(plot.margin=unit(c(0,0,0,0),"mm")) }), names(race_data_long)) e1 <- ggplot(race_data_long[[1]], aes(x=1, prop, fill=race)) + geom_bar(stat="identity", width=1) + coord_polar(theta="y") leg1 <- gtable_filter(ggplot_gtable(ggplot_build(e1)), "guide-box") p <- ggplot(ny, aes(long, lat, group=group)) + geom_polygon(colour='black', fill=NA) + theme_bw() + annotation_custom(grob = leg1, xmin = -77.5, xmax = -78.5, ymin = 44, ymax = 45) n <- length(pies) for (i in 1:n) { nms <- names(pies)[i] dat <- race_data[which(race_data$region == nms)[1], ] p <- subview(p, pies[[i]], x=unlist(dat[["long"]])[1], y=unlist(dat[["lat"]])[1], dat[["weight"]], dat[["weight"]]) } print(p) 

Questa funzionalità dovrebbe essere in ggplot, penso che stia arrivando a ggplot soonish, ma al momento è disponibile nei grafici di base. Ho pensato di pubblicarlo solo per fare un confronto.

 load(url("http://dl.dropbox.com/u/61803503/nycounty.RData")) library(plotrix) e=10^-5 myglyff=function(gi) { floating.pie(mean(gi$long), mean(gi$lat), x=c(gi[1,"white"]+e, gi[1,"black"]+e, gi[1,"hispanic"]+e, gi[1,"asian"]+e, gi[1,"other"]+e), radius=.1) #insert size variable here } g1=ny[which(ny$group==1),] plot(g1$long, g1$lat, type='l', xlim=c(-80,-71.5), ylim=c(40.5,45.1)) myglyff(g1) for(i in 2:62) {gi=ny[which(ny$group==i),] lines(gi$long,gi$lat) myglyff(gi) } 

Inoltre, ci possono essere (probabilmente sono) modi più eleganti per farlo nella grafica di base.

È una torta di New York !!

Come puoi vedere, ci sono alcuni problemi con questo che devono essere risolti. Un colore di riempimento per le contee. I grafici a torta tendono ad essere troppo piccoli o si sovrappongono. Il lat e long non prendono una proiezione, quindi le dimensioni delle contee sono distorte.

In ogni caso, sono interessato a ciò che gli altri possono inventare.

Ho scritto del codice per farlo usando la griglia grafica. C’è un esempio qui: https://qdrsite.wordpress.com/2016/06/26/pies-on-a-map/

L’objective qui era di associare i grafici a torta con punti specifici sulla mappa, e non necessariamente regioni. Per questa particolare soluzione, è necessario convertire le coordinate della mappa (latitudine e longitudine) in una scala (0,1) in modo che possano essere tracciate nelle posizioni corrette sulla mappa. Il pacchetto della griglia viene utilizzato per stampare sul viewport che contiene il pannello di stampa.

Codice:

 # Pies On A Map # Demonstration script # By QDR # Uses NLCD land cover data for different sites in the National Ecological Observatory Network. # Each site consists of a number of different plots, and each plot has its own land cover classification. # On a US map, plot a pie chart at the location of each site with the proportion of plots at that site within each land cover class. # For this demo script, I've hard coded in the color scale, and included the data as a CSV linked from dropbox. # Custom color scale (taken from the official NLCD legend) nlcdcolors <- structure(c("#7F7F7F", "#FFB3CC", "#00B200", "#00FFFF", "#006600", "#E5CC99", "#00B2B2", "#FFFF00", "#B2B200", "#80FFCC"), .Names = c("unknown", "cultivatedCrops", "deciduousForest", "emergentHerbaceousWetlands", "evergreenForest", "grasslandHerbaceous", "mixedForest", "pastureHay", "shrubScrub", "woodyWetlands")) # NLCD data for the NEON plots nlcdtable_long <- read.csv(file='https://www.dropbox.com/s/x95p4dvoegfspax/demo_nlcdneon.csv?raw=1', row.names=NULL, stringsAsFactors=FALSE) library(ggplot2) library(plyr) library(grid) # Create a blank state map. The geom_tile() is included because it allows a legend for all the pie charts to be printed, although it does not statemap <- ggplot(nlcdtable_long, aes(decimalLongitude,decimalLatitude,fill=nlcdClass)) + geom_tile() + borders('state', fill='beige') + coord_map() + scale_x_continuous(limits=c(-125,-65), expand=c(0,0), name = 'Longitude') + scale_y_continuous(limits=c(25, 50), expand=c(0,0), name = 'Latitude') + scale_fill_manual(values = nlcdcolors, name = 'NLCD Classification') # Create a list of ggplot objects. Each one is the pie chart for each site with all labels removed. pies <- dlply(nlcdtable_long, .(siteID), function(z) ggplot(z, aes(x=factor(1), y=prop_plots, fill=nlcdClass)) + geom_bar(stat='identity', width=1) + coord_polar(theta='y') + scale_fill_manual(values = nlcdcolors) + theme(axis.line=element_blank(), axis.text.x=element_blank(), axis.text.y=element_blank(), axis.ticks=element_blank(), axis.title.x=element_blank(), axis.title.y=element_blank(), legend.position="none", panel.background=element_blank(), panel.border=element_blank(), panel.grid.major=element_blank(), panel.grid.minor=element_blank(), plot.background=element_blank())) # Use the latitude and longitude maxima and minima from the map to calculate the coordinates of each site location on a scale of 0 to 1, within the map panel. piecoords <- ddply(nlcdtable_long, .(siteID), function(x) with(x, data.frame( siteID = siteID[1], x = (decimalLongitude[1]+125)/60, y = (decimalLatitude[1]-25)/25 ))) # Print the state map. statemap # Use a function from the grid package to move into the viewport that contains the plot panel, so that we can plot the individual pies in their correct locations on the map. downViewport('panel.3-4-3-4') # Here is the fun part: loop through the pies list. At each iteration, print the ggplot object at the correct location on the viewport. The y coordinate is shifted by half the height of the pie (set at 10% of the height of the map) so that the pie will be centered at the correct coordinate. for (i in 1:length(pies)) print(pies[[i]], vp=dataViewport(xData=c(-125,-65), yData=c(25,50), clip='off',xscale = c(-125,-65), yscale=c(25,50), x=piecoords$x[i], y=piecoords$y[i]-.06, height=.12, width=.12)) 

Il risultato è simile a questo:

mappa con torte

Mi sono imbattuto in quello che sembra una funzione per fare questo: “add.pie” nel pacchetto “mapplots”.

L’esempio dal pacchetto è sotto.

 plot(NA,NA, xlim=c(-1,1), ylim=c(-1,1) ) add.pie(z=rpois(6,10), x=-0.5, y=0.5, radius=0.5) add.pie(z=rpois(4,10), x=0.5, y=-0.5, radius=0.3) 

Una leggera variazione sui requisiti originali dell’OP, ma questa sembra una risposta / aggiornamento appropriati.

Se desideri una mappa Google intertriggers, a partire da googleway v2.6.0 puoi aggiungere grafici nelle info_windows di info_windows dei livelli delle mappe.

vedi ?googleway::google_charts per documentazione ed esempi

 library(googleway) set_key("GOOGLE_MAP_KEY") ## create some dummy chart data markerCharts <- data.frame(stop_id = rep(tram_stops$stop_id, each = 3)) markerCharts$variable <- c("yes", "no", "maybe") markerCharts$value <- sample(1:10, size = nrow(markerCharts), replace = T) chartList <- list( data = markerCharts , type = 'pie' , options = list( title = "my pie" , is3D = TRUE , height = 240 , width = 240 , colors = c('#440154', '#21908C', '#FDE725') ) ) google_map() %>% add_markers( data = tram_stops , id = "stop_id" , info_window = chartList ) 

inserisci la descrizione dell'immagine qui