Sovrastampa dei punti sulle mappe in R (ad es. Con ggplot2) - come spingere i punti sul lato, contrassegnare le posizioni originali, combinare i punti vicini ...?


12

Ho un database che contiene le lingue, le loro lunghezze e latitudini e un valore di funzionalità (categoria 1, categoria 2 o entrambi - nella trama questi sono contrassegnati rispettivamente in rosso, blu e verde). Possono esserci fino a tre punti per lingua e naturalmente due punti lingua possono trovarsi molto vicini l'uno all'altro.

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

Sto usando il pacchetto R ggplot2 (è quello con cui ho più familiarità, quindi sarei felice di continuare a usarlo, ma altre soluzioni sono benvenute). Ecco un ritaglio di un tentativo precedente (codice: vedi sotto 1 ):

Ritaglia dal tentativo precedente

Per ogni punto, vorrei che la posizione (approssimativa) - così come il valore - fosse ancora visibile. (Se sono presenti più punti per una singola lingua, è possibile combinarli.)

C'è un modo o ...

  • ... per spostare i punti di lato appena sufficiente in modo che non ci sia overplotting (meno casuale rispetto, ad esempio, utilizzando geom_jitter - c'è un sacco di questo tipo di schivare nel beeswarm pacchetto per esempio)?
  • ... e / o avere una sorta di "linea" che punta alla posizione originale di un punto se dovesse essere spostato?
  • ... o per combinare i punti vicini in modo che siano ancora chiari (esiste probabilmente una tecnica di lavoro che utilizza il binning, cioè stat_bin * o qualcosa con un effetto simile)?
  • ... o per creare una "trama interattiva" come quelle viste sui siti Web che possono ancora essere incluse in un pdf (sto pensando anche alle capacità di pacchetti come l' animazione e il lucido qui)? Ad esempio, sembra così su wals.info :

    wals

Da un post precedente qui, so che il pacchetto directlabels può spostare le etichette, ma non ho trovato il modo di farlo spostare anche i punti.

Sentiti libero di chiedere chiarimenti!

Nota: sono consapevole del fatto che ci sono state una serie di domande sulla sovrapposizione, ma quelle che ho esaminato tutte sembravano avere uno scopo diverso (cioè statistico) (non pretendo di aver letto tutto , quindi sarei felice di accettare anche un link, ovviamente). Cercherò di elencare quei post che conosco e che potrebbero essere pertinenti (- da quello che ho letto, nessuno di questi risponde esattamente alla mia domanda.)


1 Le seguenti righe di codice hanno creato il ritaglio dall'alto.

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'è qualcosa che posso migliorare per rendere la domanda più facile da capire e rispondere? Per favore fatemi sapere se avete qualche idea!
mag

1
Questa non è una domanda con cui ho delle competenze pertinenti con cui collaborare, ma l'ho votata per farlo apparire un po 'più alto in alcune liste. Se non ricevi alcun commento che aiuti a migliorarlo, e in ogni caso, ti consiglio di rivederlo
rivederlo

Sto pensando che potresti voler utilizzare alcune funzionalità grafiche orientate alla forza. Non sono sicuro di come farlo e di mantenere alcuni punti ancorati, ma quello che sto pensando è identificare tutti i cluster (mediante una funzione di raggruppamento di prossimità) e utilizzare il centroide del cluster come un'ancora e lasciare fluttuare i suoi membri (e non tracciare il centroide stesso - semplicemente usandolo per ancorare i vertici collegati nel suo piccolo grafico). E, naturalmente, se alcuni cluster hanno un solo membro, anche quelli dovrebbero essere ancorati alla loro posizione.
aaryno,

Non ho seguito il paragrafo "... sembra che si applichi di nuovo solo ai grafici a dispersione", perché si tratta di un diagramma a dispersione.
whuber

Devo ammettere che devo aver usato un termine sbagliato - quello che intendevo dire con scatterplot era il tipico diagramma statico in cui la posizione è generalmente meno importante rispetto al tipo di trama che abbiamo qui (= una mappa - se i punti vengono spostati qui, è ovvio subito).
mag

Risposte:


2

Finora ho trovato solo una soluzione abbastanza decente: il pacchetto packcircles R potrebbe essere stato progettato per un altro scopo, ma fa un buon lavoro allontanando i punti l'uno dall'altro (vedi anche il corrispondente post sul blog ). Potrei non capire tutto il funzionamento interno di questo pacchetto, ma per fortuna, come troverai, il file di esempio dal sito Web può essere usato quasi direttamente - tutto ciò che devi cambiare sono i nomi delle variabili, la distanza tra i cerchi (o punti) , a seconda delle funzioni utilizzate) e dei "limiti" del grafico (ovvero 180 °).

(Alla fine tutto si riduce alla circleLayout()funzione, che accetta un frame di dati con colonne lon, lat e radius (cioè distanza) e due vettori xlim / ylim 2 numerici - restituisce il frame di dati con posizioni dei punti migliorate.)

"Trama" che di solito viene creata da packcircles - puoi vederlo già funzionante qui. carta geografica

  • confronta questa mappa "dopo" con lo snippet di mappa "prima" della domanda

0

Qualcosa del genere, forse?

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

Vedo. Hai provato a replicare le "linee nella posizione originale" dallo screenshot di wals.info, vero? È un inizio, immagino. Ma se lo vedo correttamente, non risolverà la parte migliore del mio problema (ad es. I punti si sovrappongono ancora).
mag

Il resto dovrebbe essere manipolazione del frame di dati. Un ciclo if / for può governare la spaziatura - un'affermazione al suo interno può anche dire che se la spaziatura tra i punti è inferiore a x, contrassegnarli come tali e che il marcatore può essere usato per concatenare i punti

spero che qualcuno, o tu, possa sistemare il mio brutto per i loop. In bocca al lupo.

@InNoam: In effetti, sono aperto a suggerimenti su come potrebbe funzionare questa "manipolazione del frame di dati".
maggio
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.