ชี้จุดลงบนแผนที่ใน R (เช่นกับ ggplot2) - วิธีผลักจุดไปด้านข้างทำเครื่องหมายตำแหน่งเดิมรวมจุดที่อยู่ใกล้ ...


12

ฉันมีฐานข้อมูลที่ประกอบด้วยภาษาลองจิจูดและละติจูดและค่าคุณสมบัติ (ทั้งประเภท 1, ประเภท 2 หรือทั้งสองอย่าง - ในพล็อตเหล่านี้จะมีสีแดงน้ำเงินและเขียวตามลำดับ) อาจมีมากถึงสามจุดต่อภาษาและโดยปกติแล้วคะแนนภาษาสองจุดอาจอยู่ใกล้กันมาก

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

ฉันใช้ Rg แพ็คเกจ ggplot2 (นั่นคือสิ่งที่ฉันคุ้นเคยมากที่สุดดังนั้นฉันยินดีที่จะใช้มันต่อไป - แต่ก็ยินดีต้อนรับโซลูชันอื่น ๆ ด้วย) นี่คือการครอบตัดจากความพยายามก่อนหน้า (รหัส: ดูด้านล่าง1 ):

ครอบตัดจากความพยายามก่อนหน้า

สำหรับทุกจุดฉันต้องการตำแหน่ง (หยาบ) - รวมถึงค่า - ยังสามารถมองเห็นได้ (หากมีหลายจุดสำหรับภาษาเดียวอาจรวมกันได้)

มีวิธีใดบ้าง ...

  • ... เพื่อย้ายจุดไปด้านข้างมากพอที่จะไม่มีการ overplotting (สุ่มน้อยกว่าพูดโดยใช้ geom_jitter - มีจำนวนมากแบบนั้นหลบในแพ็คเกจbeeswarm )?
  • ... และ / หรือมี "เส้น" บางชนิดที่ชี้ไปที่ตำแหน่งเดิมของจุดถ้าต้องย้ายหรือไม่
  • ... หรือเพื่อรวมคะแนนแบบใกล้ชิดในแบบที่พวกเขายังคงชัดเจน (อาจมีเทคนิคการทำงานออกมีที่ใช้ binning เช่น stat_bin * หรือสิ่งที่มีผลที่คล้ายกัน)?
  • ... หรือเพื่อสร้าง "แผนแบบโต้ตอบ" เหมือนที่เห็นบนเว็บไซต์ที่ยังสามารถรวมอยู่ในรูปแบบ pdf ได้ (ฉันกำลังคิดถึงความสามารถของแพ็คเกจเช่นภาพเคลื่อนไหวและเงาที่นี่) ตัวอย่างเช่นมีลักษณะเช่นนี้ในwals.info :

    Wals

จากโพสต์ก่อนหน้านี้ที่นี่ฉันรู้ว่าแพคเกจdirectlabelsสามารถย้ายป้ายกำกับได้ แต่ฉันไม่พบวิธีที่จะทำให้ได้คะแนนเช่นกัน

อย่าลังเลที่จะขอคำชี้แจง!

หมายเหตุ: ฉันทราบดีว่ามีคำถามมากมายเกี่ยวกับการ overplotting แต่คำถามที่ฉันได้ตรวจสอบทั้งหมดดูเหมือนจะมีจุดประสงค์ที่แตกต่างกัน (เช่นสถิติ) (ฉันไม่ได้อ้างว่าได้อ่านมันทั้งหมดดังนั้นฉันจึง ' ยินดีที่จะยอมรับการเชื่อมโยงเช่นกันแน่นอน) ฉันจะพยายามแสดงรายการโพสต์ที่ฉันรู้และอาจเกี่ยวข้อง (- จากสิ่งที่ฉันอ่านไม่มีคำตอบที่ตรงกับคำถามของฉัน)


1รหัสต่อไปนี้สร้างการครอบตัดจากด้านบน

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

มีสิ่งใดบ้างที่ฉันสามารถปรับปรุงเพื่อทำให้คำถามเข้าใจและตอบได้ง่ายขึ้น? โปรดแจ้งให้เราทราบหากคุณมีความคิดใด ๆ !
พฤษภาคม

1
นี่ไม่ใช่คำถามที่ฉันมีทักษะที่เกี่ยวข้องเพื่อช่วย แต่ฉันได้ upvoted มันเพื่อให้ปรากฏที่สูงขึ้นเล็กน้อยในบางรายการ หากคุณไม่ได้รับความคิดเห็นใด ๆ ที่ช่วยปรับปรุงและในกรณีใด ๆ ฉันขอแนะนำให้ตรวจทาน / ทบทวนเป็นระยะบ่อยครั้งโดยคำนึงถึงคำแนะนำที่meta.gis.stackexchange.com/a/3353
PolyGeo

ฉันคิดว่าคุณอาจต้องการใช้ฟังก์ชั่นกราฟที่บังคับทิศทาง ฉันไม่แน่ใจว่าจะทำอย่างไรและรักษาจุดบางจุดไว้ แต่สิ่งที่ฉันคิดคือการระบุกลุ่มทั้งหมด (ตามฟังก์ชั่นการจัดกลุ่มความใกล้ชิด) และใช้เซนทรอยด์คลัสเตอร์เป็นจุดยึดและปล่อยให้สมาชิกลอยตัว การวางแผนเซนทรอยด์ด้วยตัวเอง - ใช้เพื่อยึดจุดยอดที่เชื่อมต่อในกราฟเล็ก ๆ ของมัน) และแน่นอนถ้ากลุ่มใดมีสมาชิกเพียงคนเดียวก็ควรที่จะยึดตำแหน่งของพวกเขาเช่นกัน
aaryno

ฉันไม่ได้ติดตามไปที่ "... ดูเหมือนว่าจะนำไปใช้กับ scatterplots อีกครั้งเท่านั้น" เพราะนี่เป็น scatterplot
whuber

ฉันยอมรับว่าฉันต้องใช้คำผิด - สิ่งที่ฉันหมายถึงโดยscatterplotคือscatterplotเชิงสถิติทั่วไปซึ่งตำแหน่งโดยทั่วไปมีความสำคัญน้อยกว่าในรูปแบบของพล็อตที่เรามีที่นี่ (= แผนที่ - ถ้ามีการเลื่อนจุดที่นี่ ทันที)
maj

คำตอบ:


2

เพื่อให้ห่างไกลที่ฉันได้พบเพียงหนึ่งค่อนข้างดีมองหาวิธีแก้ปัญหาการpackcirclesแพคเกจ R อาจได้รับการออกแบบมาเพื่อวัตถุประสงค์อื่น แต่มันจะทำงานที่ดีผลักดันจุดออกจากกัน (ยังเห็นสอดคล้องกันบล็อกโพสต์ ) ฉันอาจไม่เข้าใจการทำงานภายในทั้งหมดของแพคเกจนี้ แต่โชคดีที่คุณจะพบไฟล์ตัวอย่างจากเว็บไซต์ที่สามารถใช้งานได้โดยตรงเกือบทั้งหมด - ทุกคนต้องเปลี่ยนคือชื่อตัวแปรระยะห่างระหว่างวงกลม (หรือจุด ขึ้นอยู่กับฟังก์ชันที่คุณใช้) และ "ขีด จำกัด " ของกราฟ (เช่น 180 °)

(ในที่สุดมันทั้งหมดลงมาที่circleLayout()ฟังก์ชั่นซึ่งใช้กรอบข้อมูลที่มีคอลัมน์ lon, lat และ radius (เช่นระยะทาง) และสองเวกเตอร์ xlim / ylim 2 ตัวเลข - มันส่งคืน data frame พร้อมตำแหน่งของจุดที่ดีขึ้น)

"พล็อต" ที่มักจะถูกสร้างขึ้นโดย packcircles - คุณสามารถดูได้ทำงานที่นี่แล้ว แผนที่

  • โปรดเปรียบเทียบแผนที่ 'after' กับส่วนย่อย 'before' map จากคำถาม

0

บางสิ่งเช่นนี้บางที

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

ฉันเห็น. คุณพยายามจำลอง "บรรทัดไปยังตำแหน่งเดิม" จากภาพหน้าจอจาก wals.info ใช่ไหม มันเป็นการเริ่มต้นฉันเดา แต่ถ้าฉันเห็นสิ่งนี้ถูกต้องมันจะไม่แก้ปัญหาส่วนที่ดีกว่าของฉัน (เช่นคะแนนยังทับซ้อนกัน)
พฤษภาคม

ส่วนที่เหลือควรเป็นการจัดการกรอบข้อมูล ถ้า / สำหรับห่วงสามารถควบคุมระยะห่าง - คำสั่งนั้นยังสามารถพูดได้ว่าถ้าระยะห่างระหว่างถึงจุดน้อยกว่า x ทำเครื่องหมายพวกเขาเช่นนี้และเครื่องหมายที่สามารถใช้ในการเชื่อมต่อจุด

หวังว่าใครบางคนหรือคุณสามารถแก้ไขลูน่าเกลียดของฉัน โชคดี.

@InNoam: ที่จริงแล้วฉันเปิดใจกับคำแนะนำว่า 'การจัดการเฟรมข้อมูล' นี้ทำงานอย่างไร
maj
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.