Điểm quá mức trên các bản đồ trong R (ví dụ với ggplot2) - làm thế nào để đẩy các điểm sang một bên, đánh dấu các vị trí ban đầu, kết hợp các điểm gần nhau?


12

Tôi đã có một cơ sở dữ liệu chứa các ngôn ngữ, kinh độ và vĩ độ của chúng và một giá trị tính năng (loại 1, loại 2 hoặc cả hai - trong lô này lần lượt được đánh dấu màu đỏ, xanh lam và xanh lục). Có thể có tối đa ba điểm cho mỗi ngôn ngữ và tự nhiên hai điểm ngôn ngữ có thể nằm rất gần nhau.

    name            longitude   latitude    sp_sum
1   Modern Armenian 45          40          both
2   Modern Armenian 45          40          both
3   Modern Armenian 45          40          spatial
4   Dieri           138         -28.1667    both
5   Dieri           138         -28.1667    both
6   Finnish         25.5577     64.7628     non-spatial
7   Crimean Tatar   28.1418     43.8398     spatial
8   Ese Ejja        -67.515     -11.7268    non-spatial
9   Makhuwa         38.8052     -14.8509    non-spatial
...

Tôi đang sử dụng gói R ggplot2 (đó là gói tôi quen thuộc nhất, vì vậy tôi rất vui khi tiếp tục sử dụng nó - nhưng các giải pháp khác cũng được hoan nghênh). Đây là một cắt từ một lần thử trước (mã: xem bên dưới 1 ):

Cắt từ lần thử trước

Đối với mọi điểm, tôi muốn vị trí (thô) - cũng như giá trị - vẫn hiển thị. (Nếu có nhiều điểm cho một ngôn ngữ, chúng có thể được kết hợp.)

Có cách nào ...

  • ... để di chuyển các điểm sang một bên vừa đủ để không có sự thay thế quá mức (ít ngẫu nhiên hơn, bằng cách sử dụng geom_jitter - chẳng hạn như có rất nhiều kiểu né tránh trong gói sáp ong )?
  • ... và / hoặc có một số loại "đường thẳng" chỉ đến vị trí ban đầu của một điểm nếu nó phải được di chuyển?
  • ... Hoặc để kết hợp các điểm gần nhau theo cách mà chúng vẫn rõ ràng (có thể có một kỹ thuật làm việc ngoài kia sử dụng binning, tức là stat_bin * hoặc một cái gì đó có hiệu ứng tương tự)?
  • ... Hoặc để tạo một "cốt truyện tương tác" như những gì được thấy trên các trang web vẫn có thể được đưa vào pdf (Tôi cũng đang nghĩ về khả năng của các gói như hoạt hìnhsáng bóng ở đây)? Ví dụ: nó trông như thế này trên wals.info :

    wals

Từ một bài viết trước đây ở đây, tôi biết rằng gói directlabels có thể di chuyển nhãn, nhưng tôi chưa tìm được cách nào để làm cho nó di chuyển các điểm.

Hãy yêu cầu làm rõ!

Lưu ý: Tôi biết rằng đã có một số câu hỏi về việc đặt quá mức, nhưng những câu hỏi mà tôi đã xem xét dường như có một mục đích khác (tức là thống kê) (tôi không khẳng định đã đọc hết , vì vậy tôi d, vui vẻ chấp nhận một liên kết là tốt, tất nhiên). Tôi sẽ cố gắng liệt kê những bài đăng mà tôi biết và nó có thể có liên quan (- từ những gì tôi đã đọc, không ai trong số này trả lời chính xác câu hỏi của tôi.)


1 Các dòng mã sau đây đã tạo crop từ phía trên.

library(OpenStreetMap)
library(ggplot2)

data <- read.csv(header = T, sep = ",", dec = ".", quote= "'",
text = "'','name','longitude','latitude','sp_sum'
'1','Modern Armenian',45,40,'both'
'2','Modern Armenian',45,40,'both'
'3','Modern Armenian',45,40,'spatial'
'4','Dieri',138,-28.1667,'both'
'5','Dieri',138,-28.1667,'both'
'6','Finnish',25.5577,64.7628,'non-spatial'
'7','Crimean Tatar',28.1418,43.8398,'spatial'
'8','Sochiapam Chinantec',-96.6079,17.7985,'non-spatial'
'9','Ese Ejja',-67.515,-11.7268,'non-spatial'
'10','Makhuwa',38.8052,-14.8509,'non-spatial'
'11','Mualang',111.077,0.31083,'non-spatial'
'12','Martuthunira',116.607,-20.9294,'non-spatial'
'13','Evenki',108.626,53.85,'both'
'14','Afrikaans',30,-22,'both'
'15','Male (Ethiopia)',36.9892,5.91975,'both'
'16','Manchu',126.557,47.3122,'both'
'17','Dime',36.3329,6.20951,'non-spatial'
'18','Koorete',37.8679,5.80545,'non-spatial'
'19','Wolaytta',37.7537,6.32668,'both'
'20','Dizin',35.5763,6.1405,'both'")

map <- openproj(openmap(c(85, -179.9), c(-60, 179.9), zoom = 2, type = "nps"))
plot <- autoplot(map) + 
  geom_point(data = data, aes(x = longitude, y = latitude),
             color = "white", alpha = 0.8, size = 8) +
  geom_point(data = data, aes(x = longitude, y = latitude, color = sp_sum),
             alpha = 0.3, size = 4)
plot

Có bất cứ điều gì tôi có thể cải thiện để làm cho câu hỏi dễ hiểu và trả lời hơn không? Vui lòng cho tôi biết nếu bạn có bất kì ý kiến ​​nào!
maj

1
Đây không phải là một câu hỏi tôi có các kỹ năng liên quan để hỗ trợ nhưng tôi đã nâng cấp nó để làm cho nó xuất hiện cao hơn một chút trong một số danh sách. Nếu bạn không nhận được bất kỳ nhận xét nào giúp cải thiện nó và trong mọi trường hợp, tôi khuyên bạn nên xem xét / sửa đổi nó trong khoảng thời gian thường xuyên thực hiện theo lời khuyên được cung cấp tại meta.gis.stackexchange.com/a/3353
PolyGeo

Tôi nghĩ rằng bạn có thể muốn sử dụng một số chức năng đồ thị hướng lực. Tôi không chắc chắn làm thế nào để làm điều đó và giữ một số điểm neo, nhưng điều tôi nghĩ là xác định tất cả các cụm (bằng một số chức năng nhóm gần) và sử dụng cụm trung tâm làm neo và để các thành viên của nó nổi (và không vẽ sơ đồ trung tâm - chỉ cần sử dụng nó để neo các đỉnh được kết nối trong biểu đồ nhỏ của nó). Và tất nhiên, nếu bất kỳ cụm nào chỉ có một thành viên thì chúng cũng nên được neo vào vị trí của chúng.
aaryno

Tôi đã không bỏ qua một bên tại "... một lần nữa dường như chỉ áp dụng cho các biểu đồ phân tán", bởi vì đây một biểu đồ phân tán.
whuber

Tôi thừa nhận tôi đã sử dụng một thuật ngữ sai - điều tôi muốn nói bởi scatterplot là phân tán thống kê điển hình trong đó vị trí thường ít quan trọng hơn trong loại cốt truyện chúng ta có ở đây (= bản đồ - nếu các điểm được di chuyển ở đây, thì rõ ràng ngay).
maj

Câu trả lời:


2

Cho đến nay tôi chỉ tìm thấy một cách giải quyết khá tốt: Gói packcircles R có thể được thiết kế cho mục đích khác, nhưng nó làm rất tốt khi đẩy các điểm ra xa nhau (cũng xem bài đăng trên blog tương ứng ). Tôi có thể không hiểu tất cả các hoạt động bên trong của gói này, nhưng may mắn thay, như bạn sẽ thấy, tệp ví dụ từ trang web có thể được sử dụng gần như trực tiếp - tất cả một nhu cầu thay đổi là tên biến, khoảng cách giữa các vòng tròn (hoặc điểm , tùy thuộc vào các chức năng bạn sử dụng) và "giới hạn" của biểu đồ (tức là 180 °).

(Cuối cùng, tất cả đều thuộc về circleLayout()hàm, lấy một khung dữ liệu với các cột lon, lat và bán kính (tức là khoảng cách) và hai vectơ xlim / ylim 2 số - nó trả về khung dữ liệu với các vị trí điểm được cải thiện.)

"Âm mưu" thường được tạo bởi packcircles - bạn có thể thấy nó hoạt động ở đây rồi. bản đồ

  • vui lòng so sánh bản đồ 'sau' này với đoạn trích bản đồ 'trước' từ câu hỏi

0

Một cái gì đó như thế này, có lẽ?

data$spacing_x = 5
data$spacing_y = 5

for(i in 2:nrow(data)) {
  if( abs(data$latitude[i]-data$latitude[i+1]) < 2 ) {
    data$spacing_y[i] = data$spacing_y + 6 +jitter(data$spacing_y,8)
    data$spacing_y[i+1] = data$spacing_y + 6 + jitter(data$spacing_y,8)
  }
}

for(i in 2:nrow(data)) {
     if( abs(data$longitude[i]-data$longitude[i+1]) < 2 ) {
      data$spacing_x[i] = data$spacing_x + jitter(data$spacing_x,4)
      data$spacing_x[i+1] = data$spacing_x +jitter(data$spacing_x,4)
     }
}

for(i in 2:nrow(data)) {
  if( abs(data$spacing_y[i]-data$spacing_y[i+1]) < 1.5 ) {
    data$spacing_y[i] = data$spacing_y + 2 
    data$spacing_y[i+1] = data$spacing_y + 2
  }
}

for(i in 2:nrow(data)) {
  if( abs(data$spacing_x[i]-data$spacing_x[i+1]) < 1.5 ) {
    data$spacing_x[i] = data$spacing_x + 2 
    data$spacing_x[i+1] = data$spacing_x + 2
  }
}


plot = autoplot(map) + 
  geom_segment(data = data
               , mapping=aes(x=longitude
                             , y=latitude
                             , xend=longitude + spacing_x
                             , yend=latitude + spacing_y)
               , size=0.5, color="black"
               , alpha = 0.9) +
  geom_point(data = data
             , aes(x = longitude+spacing_x
                  , y = latitude+spacing_y)
             , color = "white"
             , alpha = 0.8, size = 8) +
  geom_point(data = data
             , aes(x = longitude+spacing_x
                   , y = latitude+spacing_y
                   , color = sp_sum)
             , alpha = 0.3, size = 4)
  xlab("") +
  ylab("")
plot

Tôi hiểu rồi. Bạn đã cố sao chép "đường thẳng đến vị trí ban đầu" từ ảnh chụp màn hình từ wals.info, phải không? Đó là một sự khởi đầu, tôi đoán vậy. Nhưng nếu tôi thấy điều này một cách chính xác, nó sẽ không giải quyết được phần tốt hơn của vấn đề của tôi (ví dụ: các điểm vẫn chồng chéo).
maj

Phần còn lại nên là thao tác khung dữ liệu. Một vòng lặp if / for có thể chi phối khoảng cách - một câu lệnh trong đó cũng có thể nói rằng nếu khoảng cách giữa các điểm nhỏ hơn x, hãy đánh dấu chúng như vậy và có thể sử dụng điểm đánh dấu đó để ghép các điểm

hy vọng ai đó, hoặc bạn, có thể sửa chữa những vòng lặp xấu xí của tôi. Chúc may mắn.

@InNoam: Trên thực tế, tôi cởi mở với các gợi ý về cách 'thao tác khung dữ liệu' này có thể hoạt động.
maj
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.