2013-07-31 15 views
6

Sto provando a suddividere una mappa degli Stati Uniti in più finestre (alcune delle quali contengono lo stesso stato due volte). Mi piacerebbe che le scale fossero costanti (in modo che le mappe non venissero distorte) ma minimizzassero lo spazio tra le mappe. Non posso usare facet_wrap (a causa della natura sovrapposta delle regioni - e comunque, facet_wrap non può avere scale fisse e xlim differenti per ogni finestra). Qualche suggerimento su come migliorare la spaziatura sui risultati?Organizzare ggplot più oggetti mantenendo l'altezza costante

require(data.table) 
require(ggplot2) 
require(maps) 
require(gridExtra) 
all_states <- as.data.table(map_data("state")) 

setnames(all_states,"region","state") 

##define regions with overlapping states 
weco.states <- c("oregon","washington","california") 
west.states <- c("washington","montana", "idaho","utah","nevada","arizona","new mexico", 
    "wyoming","colorado","south dakota","texas") 
east.states <- c(setdiff(unique(all_states$state), union(weco.states,west.states)), 
    "texas","south dakota") 
all_states[,c("weco","west","east"):=FALSE] 
all_states[state%in% weco.states, weco:=TRUE] 
all_states[state%in% west.states, west:=TRUE] 
all_states[state%in% east.states, east:=TRUE] 


p.regbase <- ggplot() + coord_equal() +ylim(c(25,50)) 
p.weco <- p.regbase + geom_polygon(data=all_states[(weco),], aes(x=long, y=lat, group = group),colour="white", fill="grey") 
p.west <- p.regbase + geom_polygon(data=all_states[(west),], aes(x=long, y=lat, group = group),colour="white", fill="grey") 
p.east <- p.regbase + geom_polygon(data=all_states[(east),], aes(x=long, y=lat, group = group),colour="white", fill="grey") 

print(arrangeGrob(p.weco,p.west,p.east,ncol=3,nrow=1)) 

a seconda di come a ridimensionare la finestra grafica nella GUI di Windows, i risultati sono o cattivo (scale sono diverse) enter image description here

o decenti (stesse altezze), ma non c'è troppo spazio: Come può Mi libero dello spazio extra?

enter image description here

+0

si può passare 'larghezze = unità (c (1, 2, 3), "nullo")' a 'arrangeGrob', e modificare i relativi fattori manualmente. – baptiste

+0

Questo non risolve il fatto che organizzareGrob riempie lo spazio vuoto attorno al primo grafico. – Michael

+0

Non vedo come questo ha risolto questo problema. Se può, potresti dimostrare come? Ho fornito codice di esempio completamente utilizzabile ... – Michael

risposta

5

Ecco una soluzione che utilizza facet_grid() e l'impostazione un po 'oscura theme(aspect.ratio=1). La trama non è perfetta, ma spero che ti dia la maggior parte di ciò che ti serve. Si noti che gli stati sembrano un po 'più ampi di quanto dovrebbero. Apparentemente 1 grado di latitudine non è evidentemente la stessa distanza di 1 grado di longitudine negli Stati Uniti.

# Create a new factor column for faceting. 
newfactor = ifelse(all_states$weco, "weco", 
          ifelse(all_states$west, "west", "east")) 

# Manually specify sort order of factor levels. 
newfactor = factor(as.character(newfactor), levels=c("weco", "west", "east")) 

all_states$region = newfactor 

plot_1 = ggplot(all_states, aes(x=long, y=lat, group=group)) + 
     geom_polygon(colour="white", fill="grey") + 
     facet_grid(. ~ region, space="free", scales="free") + 
     theme(aspect.ratio=1) 

ggsave("plot_1.png", plot=plot_1, height=4, width=8, dpi=150) 

enter image description here

+0

Questo è quasi perfetto - Mi piacerebbe che alcuni stati si trovino in più regioni, ma questo è fatto facilmente copiandoli e trasferendoli (quindi ci sono due serie di righe di washington, ad esempio una in weco e una in west). Grazie mille! Stavo davvero iniziando a credere che non fosse possibile. Il problema degli stati estesi è dovuto al fatto che la mappa non sta usando le coordinate proiettate, il che non è un grosso problema. – Michael

+1

'+ coord_map (" lambert ", lat0 = 25, lat1 = 50)' proietta le mappe (in lambert, in questo esempio) – Michael

5

Chiariamo alcune cose.

  • grid.arrange non "aggiunge padding", si limita a mettere insieme i solchi in una griglia. È possibile modificare la larghezza di ciascuna cella della riga,

grid.newpage() 
pushViewport(viewport(width=5, height=2.5, default.units="in")); 
gt = grobTree(rectGrob(), circleGrob()) 
grid.arrange(gt, gt, gt, nrow=1, newpage=FALSE, 
      widths = unit(c(1, 2, 3), "null")) 
upViewport() 

enter image description here

  • allineando piazzole è facile quando non hanno una proporzione fissa, per esempio utilizzando gtable ::: cbind_gtable

  • la proporzione fissa è codificato nel gtable attraverso relative unità di griglia nullo, come si può facilmente verificare con,


g = ggplotGrob(p.weco) 
g[["heights"]][3] # 2.37008405379269 is the aspect ratio for that plot panel 

  • il motivo per cui l'impostazione delle larghezze non funziona bene con il rapporto fisso-formato ggplot2 è duplice: i) è difficile indovinare quale larghezza relativa dovremmo assegnare, perché dipende dal rapporto aspetto che è stato calcolato in base agli intervalli di dati; ii) la larghezza e l'altezza del dispositivo dovrebbero essere regolati in base alle tre proporzioni per evitare spazio vuoto supplementare (necessario mantenere le proporzioni corrette)

Questi problemi have been discussed here; Non conosco una soluzione elegante e generale.

Problemi correlati