2015-06-21 19 views
7

Vorrei tracciare una traiettoria su una mappa di base e visualizzare le etichette dei paesi (nomi) come una sovrapposizione.Etichette dei paesi sulla mappa di base

Ecco il codice corrente e la mappa si produce:

import pandas as pd 
import matplotlib.pyplot as plt 
from mpl_toolkits.basemap import Basemap 


path = "path\\to\\data" 

animal_data = pd.DataFrame.from_csv(path, header=None) 
animal_data.columns = ["date", "time", "gps_lat", "gps_long"] 

# data cleaning omitted for clarity 

params = { 
     'projection':'merc', 
     'lat_0':animal_data.gps_lat.mean(), 
     'lon_0':animal_data.gps_long.mean(), 
     'resolution':'h', 
     'area_thresh':0.1, 
     'llcrnrlon':animal_data.gps_long.min()-10, 
     'llcrnrlat':animal_data.gps_lat.min()-10, 
     'urcrnrlon':animal_data.gps_long.max()+10, 
     'urcrnrlat':animal_data.gps_lat.max()+10 
} 
map = Basemap(**params) 

map.drawcoastlines() 
map.drawcountries() 
map.fillcontinents(color = 'coral') 
map.drawmapboundary()   

x, y = map(animal_data.gps_long.values, animal_data.gps_lat.values) 

map.plot(x, y, 'b-', linewidth=1)  
plt.show() 

Il risultato è la mappa: Migration

Si tratta di una mappa della traiettoria di un uccello migratore. Mentre questa è una mappa molto bella (!), Ho bisogno di etichette di nomi di paesi, quindi è facile determinare i paesi in cui l'uccello sta volando.

C'è un modo semplice per aggiungere i nomi dei paesi?

+2

Wow, quell'uccellino sta viaggiando a una certa distanza! Se hai bisogno di nomi e coordinate di paesi, dai un'occhiata a [questa domanda] (http://stackoverflow.com/questions/2702309/need-a-list-of-all-countries-in-the-world-with-a -longitude-e-latitudine-coordin). Per tracciare il testo su una mappa, dare un'occhiata all'esempio di pressione su [questa pagina] (http://matplotlib.org/basemap/users/examples.html), sembra che tu possa semplicemente fare "plt.text" (x, y, testo) '. –

+0

Grazie! Questo è stato molto utile. Inserirò presto la soluzione completa qui sotto. –

risposta

6

La mia soluzione si basa su un file di dati esterno che potrebbe essere disponibile o meno in futuro. Tuttavia, dati simili possono essere trovati altrove, quindi non dovrebbe essere un problema.

In primo luogo, il codice per la stampa delle etichette paese-name:

import pandas as pd 
import matplotlib.pyplot as plt 
from mpl_toolkits.basemap import Basemap 

class MyBasemap(Basemap):  
    def printcountries(self, d=3, max_len=12): 
     data = pd.io.parsers.read_csv("http://opengeocode.org/cude/download.php?file=/home/fashions/public_html/opengeocode.org/download/cow.txt", 
             sep=";", skiprows=28) 
     data = data[(data.latitude > self.llcrnrlat+d) & (data.latitude < self.urcrnrlat-d) & (data.longitude > self.llcrnrlon+d) & (data.longitude < self.urcrnrlon-d)] 
     for ix, country in data.iterrows():        
       plt.text(*self(country.longitude, country.latitude), s=country.BGN_name[:max_len]) 

Tutto questo non è quello di scaricare un database paese posizione dalla here, quindi selezionare i paesi che sono attualmente sulla mappa ed etichettarli .

Il codice completo:

import pandas as pd 
import matplotlib.pyplot as plt 
from mpl_toolkits.basemap import Basemap 

class MyBasemap(Basemap):  
    def printcountries(self, d=3, max_len=12): 
     data = pd.io.parsers.read_csv("http://opengeocode.org/cude/download.php?file=/home/fashions/public_html/opengeocode.org/download/cow.txt", 
             sep=";", skiprows=28) 
     data = data[(data.latitude > self.llcrnrlat+d) & (data.latitude < self.urcrnrlat-d) & (data.longitude > self.llcrnrlon+d) & (data.longitude < self.urcrnrlon-d)] 
     for ix, country in data.iterrows():        
       plt.text(*self(country.longitude, country.latitude), s=country.BGN_name[:max_len]) 


path = "path\\to\\data" 

animal_data = pd.DataFrame.from_csv(path, header=None) 
animal_data.columns = ["date", "time", "gps_lat", "gps_long"] 

params = { 
     'projection':'merc', 
     'lat_0':animal_data.gps_lat.mean(), 
     'lon_0':animal_data.gps_long.mean(), 
     'resolution':'h', 
     'area_thresh':0.1, 
     'llcrnrlon':animal_data.gps_long.min()-10, 
     'llcrnrlat':animal_data.gps_lat.min()-10, 
     'urcrnrlon':animal_data.gps_long.max()+10, 
     'urcrnrlat':animal_data.gps_lat.max()+10 
} 

plt.figure() 
map = MyBasemap(**params) 

map.drawcoastlines() 
map.fillcontinents(color = 'coral') 
map.drawmapboundary()   
map.drawcountries() 
map.printcountries() 

x, y = map(animal_data.gps_long.values, animal_data.gps_lat.values) 

map.plot(x, y, 'b-', linewidth=1)  
plt.show() 

e, infine, il risultato:

labeld-map

Chiaramente questo non è così accuratamente etichettato come si potrebbe sperare, e alcune euristiche per quanto riguarda le dimensioni del paese, la lunghezza del nome e la dimensione della mappa dovrebbero essere implementate per renderlo perfetto, ma questo è un buon punto di partenza.

Problemi correlati