2012-11-17 17 views
16

Próbuję zrobić mapę z dwiema legendami oznaczającymi kształt i kolor ("Typ" i "Org" w poniższym przykładzie) i mieć wstawione legendy. Mogę umieścić legendy, ale chciałbym, aby zostały one usprawiedliwione, tak aby ich lewa krawędź była wyrównana. Nie mogę zrobić nic innego niż im wyśrodkowany względem siebie:Uzasadnienie wielu legend w ggmap/ggplot2

require(ggplot2) 
require(ggmap) 
require(grid) 
require(mapproj) 

data <- data.frame(Org=rep(c("ABCDEFG","HIJKLMNOP","QRSTUVWX"),4) 
        , Type=rep(c("Y","Z"),6), Lat=runif(12,48,54.5) 
        , Long=runif(12,-133.5,-122.5)) 

osmMap <- get_map(location=c(-134,47.5,-122,55), source = 'osm') 

points <- geom_jitter(data=data, aes(Long, Lat, shape=Type 
            , colour=Org)) 

legend <- theme(legend.justification=c(0,0), legend.position=c(0,0) 
       , legend.margin=unit(0,"lines"), legend.box="vertical" 
       , legend.key.size=unit(1,"lines"), legend.text.align=0 
       , legend.title.align=0) 

ggmap(osmMap) + points + legend 

enter image description here

+1

Nie jest to bezpośrednia odpowiedź, ale można oszukać trochę za pomocą formatu, aby dostosować ich rozmiar. Spróbuj 'data $ Type <- format (data $ Type, width = 17)' po deklaracji danych i uruchom ponownie swój kod. –

+0

To fajna sztuczka, dzięki. Zrobię to w poniedziałek – andyteucher

Odpowiedz

19

Ta opcja jest obecnie dostępna w ggplot2 0.9.3.1, należy

ggmap(osmMap) + points + legend + theme(legend.box.just = "left") 

Stary, rozwiązanie ręczne:

Oto rozwiązanie:

require(gtable) 
require(ggplot2) 
require(ggmap) 
require(grid) 
require(mapproj) 

# Original data 
data <- data.frame(Org=rep(c("ABCDEFG","HIJKLMNOP","QRSTUVWX"),4), 
        Type=rep(c("Y","Z"),6), Lat=runif(12,48,54.5), 
        Long=runif(12,-133.5,-122.5)) 
osmMap <- get_map(location=c(-134,47.5,-122,55), source = 'google') 
points <- geom_jitter(data=data, aes(Long, Lat, shape=Type, colour=Org)) 
legend <- theme(legend.justification=c(0,0), legend.position=c(0,0), 
       legend.margin=unit(0,"lines"), legend.box="vertical", 
       legend.key.size=unit(1,"lines"), legend.text.align=0, 
       legend.title.align=0) 

# Data transformation 
p <- ggmap(osmMap) + points + legend 
data <- ggplot_build(p) 
gtable <- ggplot_gtable(data) 

# Determining index of legends table 
lbox <- which(sapply(gtable$grobs, paste) == "gtable[guide-box]") 
# Each legend has several parts, wdth contains total widths for each legend 
wdth <- with(gtable$grobs[[lbox]], c(sum(as.vector(grobs[[1]]$widths)), 
            sum(as.vector(grobs[[2]]$widths)))) 
# Determining narrower legend 
id <- which.min(wdth) 
# Adding a new empty column of abs(diff(wdth)) mm width on the right of 
# the smaller legend box 
gtable$grobs[[lbox]]$grobs[[id]] <- gtable_add_cols(
             gtable$grobs[[lbox]]$grobs[[id]], 
             unit(abs(diff(wdth)), "mm")) 
# Plotting 
grid.draw(gtable) 

Nie zależy to od Type ani od . Jednak nie wystarczyłoby posiadanie więcej niż dwóch legend. Ponadto, w przypadku wprowadzenia pewnych zmian, aby zmienić listę grobs (obiektów graficznych), może być konieczna zmiana grobs[[8]] na grobs[[i]], gdzie i jest pozycją Twoich legend, zobacz gtable$grobs i poszukaj TableGrob (5 x 3) "guide-box": 2 grobs. enter image description here

Edycja: 1. Automatyczne wykrywanie które Grob jest stół legendy, oznacza, że ​​nie trzeba wprowadzać żadnych zmian po modyfikowania innych elementów powierzchni. 2. Zmieniono obliczenia różnic szerokości, teraz kod powinien działać, gdy mając żadnych dwie legendy, czyli w bardziej skomplikowanych przypadkach, jak również, na przykład:

enter image description here

+0

Dziękuję @ Julius - działa to dobrze i dał mi pewien wgląd w używanie gtable, którego tak naprawdę nie odkryłem wcześniej. – andyteucher

+0

Nie mogę odtworzyć tego przykładu. Skąd czerpię 'osmMap'? Zakładam, że to jakiś zbiór danych. –

+1

@FaheemMitha, tak, to dane z pytania. Dodałem go do mojej odpowiedzi, a także zmieniłem 'source = 'osm'' na' source =' google'', ponieważ ten pierwszy nie działa na razie. – Julius

Powiązane problemy