2017-07-25 18 views
5

Tôi đang vẽ một ô bản đồ, nơi tôi muốn đặt một nhãn văn bản nhỏ bên trong mỗi trạng thái. Vấn đề hiện tại của tôi là văn bản đi ra ngoài giới hạn trạng thái, vì vậy nó không nhìn đẹp: enter image description hereLàm thế nào để đảm bảo tiêu đề văn bản nằm trong đối tượng đa giác?

tôi đã cố gắng sử dụng trung bình, trung bình, centroids và vân vân.

Những gì tôi muốn là mỗi văn bản là hoàn toàn bên trong hoặc bên ngoài đa giác, như ở đây: enter image description here (hình ảnh từ http://www.businessinsider.com/map-what-100-is-actually-worth-in-your-state-2015-7?IR=T)

tôi sử dụng đoạn mã sau để tạo ra hình ảnh của tôi:

library(maps) 
library(dplyr) 
library(ggplot2) 

#data 
mapbase <- map_data("state.vbm")  
data(state.vbm.center) 
df <- state.vbm.center %>% as.data.frame() %>% 
    mutate(region = unique(mapbase$region)) %>% full_join(mapbase) 


#actual plotting 
cnames <- aggregate(cbind(long, lat) ~ region, data=df, FUN=median) 
gmap<- 
    ggplot()+ 
    geom_polygon(data=df2, 
       aes(long, lat, group = region, fill = somevalue,alpha=0.3)) + 
    coord_fixed() + 
    theme_void() + 
    geom_text(data=cnames, aes(fontface=2 ,cnames$long, cnames$lat , label = "text" 
), color= "black" ,size=3,check_overlap = T, position=position_jitter(width=3, height=3) ) + 

    scale_fill_gradient(low="red",high="blue") 

Cảm ơn bạn rất nhiều cho bạn gợi ý!

Trả lời

3

Một số điểm để xem xét.

1 - nơi tối ưu cho mục đích chú thích trong một đa giác

Trong một thế giới lý tưởng, mỗi đa giác cũng tương tự như một vòng tròn, và trung tâm của nó là nơi tốt nhất để xác định vị trí một nhãn văn bản (ví dụ Texas). Trên thực tế, các khu vực bản đồ có đủ loại hình dạng, & thậm chí có thể không nằm trong một phần (ví dụ: Michigan). Điểm trung bình/điểm trung bình toán học có thể nằm trên cạnh hoặc bên ngoài đa giác (ví dụ: Florida).

R sẽ không tuyệt vời khi cố gắng tìm ra những biến chứng này. Thay vào đó, tôi sẽ sử dụng phần mềm GIS.

Tuy nhiên, nếu trường hợp sử dụng của bạn là Hoa Kỳ, bộ dữ liệu state.vbm.center đã đi kèm với một tập hợp tọa độ mặc định khá tốt. Nó bang giúp đỡ file:

state.vbm.center là tọa độ của các trung tâm nhà nước cho chú thích mục đích.

Chúng ta hãy nhìn vào nơi những điểm này là:

#data 
mapbase <- map_data("state.vbm")  
data(state.vbm.center) 

cnames <- state.vbm.center %>% as.data.frame() %>% 
    mutate(region = unique(mapbase$region)) 

#actual plotting 
ggplot()+ 
    geom_polygon(data=mapbase, 
       aes(long, lat, group = region, fill = region), 
       alpha = 0.3) + 
    coord_fixed() + theme_void() + 
    geom_point(data = cnames, 
      aes(x, y)) + 
    scale_fill_discrete(guide = F) 

center location

Đó không phải là quá tồi tàn. Nếu tất cả các bạn cần phải dán nhãn là tên nhà nước, điều này sẽ đủ:

cnames$abb <- state.abb 

ggplot()+ 
    geom_polygon(data=mapbase, 
       aes(long, lat, group = region, fill = region), 
       alpha = 0.3) + 
    coord_fixed() + theme_void() + 
    geom_text(data=cnames, 
      aes(x, y , label = abb), 
      color= "black", size=3, fontface = 2, 
      hjust = 0.5, vjust = 0.5) + #central alignment 
    scale_fill_discrete(guide = F) 

abbreviated names

2 - Lắp nhãn dài vào không gian chật hẹp

Nó rất tốt nhãn ngắn phù hợp trong đa giác bản đồ, nhưng nếu bạn muốn bao gồm thêm thông tin (tên đầy đủ của mỗi tiểu bang, tỷ lệ sinh, tỷ lệ tội phạm, tỷ lệ thất nghiệp, trình độ học vấn, phạm vi thu nhập, mật độ dân số, tỷ lệ người bỏ phiếu trong cuộc bầu cử cuối cùng, ...), cuối cùng bạn sẽ bắt đầu hết dung lượng trong wei nhỏ hơn đa giác hình thứ ba.

Cách tiếp cận kép có thể được áp dụng tại thời điểm này, giữ thông tin trong các đa giác lớn hơn, & đặt các đa giác nhỏ hơn riêng biệt ở một bên như chú giải một phần. Đối với tiểu bang Hoa Kỳ, khu vực nhà nước là một phần của tiêu chuẩn datasets gói, mà cứu chúng ta những rắc rối của việc tính toán nó:

# incorporate area information & identify small area states 
cnames$area <- state.area 
ggplot(cnames %>% 
     mutate(region = factor(region, levels = region[order(area)])), 
     aes(x = region, y = area)) + geom_col() + 
    theme_classic() + 
    theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust = 1)) 

# the first 7 states (up to Maryland) are noticeably smaller than the rest 

sorted by area size

Chọn một số vùng trống đẹp trên bản đồ của bạn cho các tiểu bang nhỏ. Tôi quyết định sắp xếp chúng theo chiều dọc trong 1 cột ở kinh độ = 140, & vĩ độ khác nhau, 0-60:

library(tidyr) 

legend.states <- cnames$region[which(cnames$area <= 10577)] 
legend.states <- as.data.frame(legend.states) 
legend.states$long1 <- 140 
legend.states$lat1 <- seq(0, 60, length.out = nrow(legend.states)) 
legend.states <- legend.states %>% 
    mutate(long2 = long1 + 5, lat2 = lat1) %>% 
    mutate(long3 = long2, lat3 = lat2 - 5) %>% 
    mutate(long4 = long1, lat4 = lat3) %>% 
    mutate(long5 = long1, lat5 = lat1) %>% 
    gather(k, v, -legend.states) %>% 
    mutate(order = as.integer(substring(k, nchar(k))), 
     k = gsub("[0-9]", "", k)) %>% 
    spread(k, v) %>% 
    rename(region = legend.states) %>% 
    mutate(group = mapbase$group[match(region, mapbase$region)]) %>% 
    select(long, lat, group, order, region) %>% 
    mutate(subregion = NA) 

# add legend polygons to the original polygon dataset 
mapbase2 <- rbind(mapbase, legend.states) 

Thay đổi chú thích phối cho các tiểu bang nhỏ, chẳng hạn rằng họ đang liên kết với vị trí hộp huyền thoại:

cnames2 <- left_join(cnames, 
        legend.states %>% filter(order %in% c(1, 4)) %>% 
         group_by(region) %>% 
         summarise(long = mean(long) + 7, 
           lat = mean(lat))) %>% 
    mutate(x = coalesce(long, x), 
     y = coalesce(lat, y), 
     hjust = ifelse(is.na(lat), 0.5, 0)) 
# left alignment (hjust=0) for small state text, central alignment (hjust=0.5) otherwise. 

Đặt tất cả mọi thứ với nhau:

ggplot()+ 
    geom_polygon(data=mapbase2, 
       aes(long, lat, group = region, fill = region), 
       alpha = 0.3) + 
    coord_fixed() + theme_void() + 
    geom_text(data=cnames2, 
      aes(x, y , label = abb, hjust = hjust), 
      size=3, fontface = 2, 
      vjust = 0.5) + 
    scale_fill_discrete(guide = F) 

legend box

(Lưu ý: đối với văn bản dài hơn, có thể bạn cũng sẽ cần tăng giới hạn trục x và/hoặc chèn ngắt dòng.)

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