Titik overplotting pada peta di R (mis. Dengan ggplot2) - bagaimana cara mendorong titik ke samping, menandai posisi asli, menggabungkan titik dekat ...?


12

Saya memiliki database yang berisi bahasa, garis bujur dan garis lintangnya serta nilai fitur (baik kategori 1, kategori 2 atau keduanya - dalam plot ini ditandai merah, biru, dan hijau). Mungkin ada hingga tiga poin per bahasa dan secara alami dua poin bahasa mungkin terletak sangat dekat satu sama lain.

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

Saya menggunakan paket R ggplot2 (yang paling saya kenal, jadi saya akan senang menggunakannya - tetapi solusi lain juga diterima). Berikut adalah hasil dari upaya sebelumnya (kode: lihat di bawah 1 ):

Pangkas dari upaya sebelumnya

Untuk setiap poin, saya ingin posisi (kasar) - dan juga nilainya - masih terlihat. (Jika ada beberapa titik untuk satu bahasa, mereka dapat digabungkan.)

Apakah ada cara baik ...

  • ... untuk memindahkan poin ke samping cukup sehingga tidak ada overplotting (kurang acak daripada, katakanlah, dengan menggunakan geom_jitter - ada banyak semacam itu menghindari dalam paket lebah misalnya)?
  • ... dan / atau memiliki semacam "garis" yang menunjuk ke posisi awal suatu titik jika harus dipindahkan?
  • ... atau untuk menggabungkan titik dekat dengan cara mereka masih jelas (mungkin ada teknik yang bekerja di luar sana yang menggunakan binning, yaitu stat_bin * atau sesuatu dengan efek yang sama)?
  • ... atau membuat "plot interaktif" seperti yang terlihat di situs web yang masih dapat dimasukkan ke dalam pdf (saya juga memikirkan kemampuan paket seperti animasi dan mengkilap di sini)? Sebagai contoh, sepertinya ini di wals.info :

    wals

Dari posting sebelumnya di sini, saya tahu bahwa paket directlabels dapat memindahkan label, tetapi saya belum menemukan cara untuk membuatnya memindahkan poin juga.

Jangan ragu untuk meminta klarifikasi!

Catatan: Saya sadar bahwa ada sejumlah pertanyaan tentang overplotting, tetapi pertanyaan yang saya teliti sepertinya memiliki tujuan yang berbeda (yaitu statistik) (saya tidak mengklaim telah membaca semuanya , jadi saya ' d akan senang menerima tautan juga, tentu saja). Saya akan mencoba daftar posting yang saya tahu dan yang mungkin relevan (- dari apa yang saya baca, tidak ada yang menjawab pertanyaan saya.)


1 Baris kode berikut membuat hasil panen dari atas.

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

Adakah yang bisa saya tingkatkan untuk membuat pertanyaan lebih mudah dipahami dan dijawab? Tolong beri tahu saya jika Anda memiliki ide!
maj

1
Ini bukan pertanyaan yang saya miliki keterampilannya untuk membantu, tetapi saya telah meningkatkannya untuk membuatnya tampak sedikit lebih tinggi dalam beberapa daftar. Jika Anda tidak mendapatkan komentar yang membantu memperbaikinya, dan dalam hal apa pun, saya sarankan meninjau / merevisinya secara berkala dengan memperhatikan saran yang ditawarkan di meta.gis.stackexchange.com/a/3353
PolyGeo

Saya pikir Anda mungkin ingin menggunakan beberapa fungsi grafik yang diarahkan secara paksa. Saya tidak yakin bagaimana melakukannya dan mempertahankan beberapa poin, tetapi yang saya pikirkan adalah mengidentifikasi semua cluster (dengan beberapa fungsi pengelompokan kedekatan) dan menggunakan centroid cluster sebagai jangkar dan membiarkan anggotanya mengapung (dan tidak merencanakan centroid itu sendiri - hanya menggunakannya untuk melabuhkan simpul yang terhubung dalam grafik kecilnya). Dan tentu saja, jika ada cluster yang hanya memiliki satu anggota maka mereka harus ditempatkan di lokasi mereka juga.
aaryno

Saya tidak mengikuti kata samping di "... sepertinya hanya berlaku untuk scatterplots," karena ini adalah scatterplot.
whuber

Saya akui saya pasti menggunakan istilah yang salah - apa yang saya maksudkan dengan scatterplot adalah tipikal sebaran statistik di mana posisi umumnya kurang penting daripada dalam jenis plot yang kita miliki di sini (= peta - jika titik-titik dipindahkan di sini, sudah jelas segera).
maj

Jawaban:


2

Sejauh ini saya telah menemukan hanya satu mencari solusi yang cukup layak: The packcircles R paket mungkin telah dirancang untuk tujuan lain, tapi itu bagus pekerjaan mendorong poin dari satu sama lain (lihat juga sesuai posting blog ). Saya mungkin tidak mengerti semua cara kerja paket ini, tetapi untungnya, seperti yang akan Anda temukan, contoh file dari situs web dapat digunakan hampir secara langsung - yang perlu diubah hanyalah nama variabel, jarak antara lingkaran (atau titik). , tergantung pada fungsi yang Anda gunakan) dan "batas" grafik (yaitu 180 °).

(Pada akhirnya semuanya tergantung pada circleLayout()fungsi, yang mengambil frame data dengan kolom lon, lat, dan radius (yaitu jarak) dan dua vektor xlim / ylim 2-numerik - mengembalikan frame data dengan posisi titik yang ditingkatkan.)

"Plot" yang biasanya dibuat oleh packcircles - Anda dapat melihatnya sudah bekerja di sini. peta

  • harap bandingkan peta 'setelah' ini dengan cuplikan peta 'sebelum' dari pertanyaan

0

Sesuatu seperti ini, mungkin?

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

Saya melihat. Anda mencoba meniru "garis ke posisi semula" dari tangkapan layar dari wals.info, bukan? Ini awal, saya kira. Tetapi jika saya melihat ini dengan benar, itu tidak akan menyelesaikan bagian yang lebih baik dari masalah saya (misalnya poin masih tumpang tindih).
maj

Sisanya harus manipulasi bingkai data. Jika / untuk loop dapat mengatur spasi - pernyataan di dalamnya juga dapat mengatakan bahwa jika jarak antara ke titik kurang dari x, tandai sebagai itu dan penanda itu dapat digunakan untuk menggabungkan titik

semoga seseorang, atau Anda, dapat memperbaiki loop jelek saya. Semoga berhasil.

@InNoam: Sebenarnya, saya terbuka terhadap petunjuk tentang bagaimana 'manipulasi bingkai data' ini bisa bekerja.
May
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.