2013-07-31 4 views
6

Ich versuche eine Karte der Vereinigten Staaten in mehrere Fenster zu teilen (von denen einige den gleichen Zustand zweimal enthalten). Ich möchte, dass die Skalen konstant bleiben (damit die Karten nicht verzerrt sind), aber auch den Abstand zwischen den Karten minimieren. Ich kann facet_wrap nicht benutzen (wegen der überlappenden Natur der Regionen - und trotzdem kann facet_wrap keine festen Skalen haben und unterschiedliche xlims für jedes Fenster haben). Irgendwelche Vorschläge, wie Sie den Abstand zu den Ergebnissen verbessern können?Anordnen von ggplot mehreren Objekten bei konstanter Höhe

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

je nachdem, wie ich das Grafikfenster in der Windows-GUI die Größe, die Ergebnisse sind entweder schlecht (Maßstab unterschiedlich) enter image description here

oder anständig (gleiche Höhe), aber es gibt zu viel Raum: Wie kann Ich werde den zusätzlichen Raum loswerden?

enter image description here

+0

Sie passieren können 'Breite = Einheit (C (1, 2, 3), "null")' 'zu arrangeGrob' und zwicken manuell die relativen Faktoren. – baptiste

+0

Dies geht nicht auf die Tatsache ein, dass arraygrob Leerzeichen um das erste Diagramm auffüllt. – Michael

+0

Ich sehe nicht, wie dies das Problem behoben hat. Wenn es möglich ist, könnten Sie das demonstrieren? Ich habe voll verwendbaren Beispielcode zur Verfügung gestellt ... – Michael

Antwort

5

Hier ist eine Lösung mit facet_grid() und die etwas obskure Einstellung theme(aspect.ratio=1). Die Handlung ist nicht perfekt, aber ich hoffe, dass es Ihnen das meiste von dem gibt, was Sie brauchen. Beachten Sie, dass die Zustände etwas breiter aussehen, als sie sollten. Anscheinend ist ein Breitengrad in den USA nicht die gleiche Entfernung wie ein Längengrad.

# 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

Das ist fast perfekt - ich möchte einige Zustände in mehreren Regionen haben, aber das ist einfach, indem man sie kopiert und sie bindet (so gibt es zum Beispiel zwei Sätze von Washington Reihen - eine in Weco und eine in West)). Danke vielmals! Ich fing wirklich an zu glauben, dass das nicht möglich war. Das Problem mit dem gestreckten Zustand ist nur darauf zurückzuführen, dass die Karte keine projizierten Koordinaten verwendet, was keine große Sache ist. – Michael

+1

'+ coord_map (" lambert ", lat0 = 25, lat1 = 50)' projiziert die Maps (in diesem Beispiel in lambert) – Michael

5

Lasst uns ein paar Dinge klären.

  • grid.arrange fügt nicht "padding" hinzu, es fügt nur grobs nebeneinander in einem Rasterlayout hinzu. Sie können die Breiten der einzelnen Zelle in der Zeile ändern,

  • 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

    • Plots Ausrichten leicht ist, wenn sie nicht über ein festes Seitenverhältnis z.B Verwendung gtable ::: cbind_gtable

    • das feste Seitenverhältnis im gtable durch relativ null Gittereinheiten codiert ist, wie man leicht mit überprüfen,


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

    • der Grund für die Einstellung der Breiten funktioniert nicht gut mit festen Seitenverhältnis ggplot2 ist zweifach: i) Es ist schwer zu erraten, welche relativen Breiten wir zuweisen sollten, weil das hängt vom Seitenverhältnis ab, das gemäß den Datenbereichen berechnet wurde; ii) die Gerätebreite und -höhe sollten ebenfalls entsprechend den drei Seitenverhältnissen eingestellt werden, um zusätzlichen Leerraum zu vermeiden (notwendig, um die korrekten Bildseitenverhältnisse beizubehalten)
    • Diese Ausgaben have been discussed here; Ich kenne keine elegante und allgemeine Lösung.

    Verwandte Themen