2012-11-17 25 views
16

Tôi đang cố tạo bản đồ với hai truyền thuyết biểu thị hình dạng và màu sắc ("Loại" và "Org" trong ví dụ bên dưới) và có chú thích inset. Tôi có thể đặt các truyền thuyết, nhưng tôi muốn chúng được để lại hợp lý để các cạnh trái của chúng xếp hàng. Tôi không thể làm cho họ bất cứ điều gì khác hơn là làm trung tâm liên quan đến nhau:Giải thích nhiều truyền thuyết trong 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

Đây không phải là một câu trả lời trực tiếp nhưng bạn có thể ăn gian một chút bằng cách sử dụng định dạng để làm cho chúng có kích thước tương đương. Hãy thử 'data $ Type <- format (dữ liệu $ Type, width = 17)' sau khi khai báo dữ liệu của bạn và chạy lại mã của bạn. –

+0

Đó là một mẹo nhỏ gọn, cảm ơn. Tôi sẽ chụp ảnh vào Thứ Hai – andyteucher

Trả lời

19

Tùy chọn này bây giờ đã có trong ggplot2 0.9.3.1, sử dụng

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

Cũ, giải pháp thủ công:

Đây là giải pháp:

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) 

Điều này không phụ thuộc vào Type hoặc Org. Tuy nhiên, điều này sẽ không đủ có hơn hai truyền thuyết. Ngoài ra, trong trường hợp bạn thực hiện một số thay đổi để danh sách các khối (đối tượng đồ họa) bị thay đổi, bạn có thể cần thay đổi grobs[[8]] thành grobs[[i]] trong đó i là vị trí của truyền thuyết, xem gtable$grobs và tìm kiếm TableGrob (5 x 3) "guide-box": 2 grobs. enter image description here

Edit: 1. Tự động phát hiện mà grob là bảng huyền thoại, tức là không có cần phải thay đổi bất cứ điều gì sau khi sửa đổi các bộ phận khác của cốt truyện. 2. Thay đổi tính toán sự khác biệt chiều rộng, bây giờ mã nên làm việc khi có bất kỳ hai huyền thoại, tức là trong trường hợp phức tạp hơn là tốt, ví dụ:

enter image description here

+0

Cảm ơn bạn @Julius - công trình này hoạt động tốt và cung cấp cho tôi một số thông tin chi tiết về việc sử dụng gtable mà tôi chưa từng khám phá trước đó. – andyteucher

+0

Tôi không thể tạo lại ví dụ này. Tôi lấy 'osmMap' từ đâu? Tôi cho rằng đây là một số bộ dữ liệu. –

+1

@FaheemMitha, vâng, đó là dữ liệu từ câu hỏi. Tôi đã thêm nó vào câu trả lời của tôi và cũng đã thay đổi 'source = 'osm'' thành' source =' google'' vì trước đây nó không hoạt động. – Julius

Các vấn đề liên quan