[Python-es] Dibujar trayectorias sobre un mapa usando matplotlib-basemap

283 views
Skip to first unread message

Boris Vladimir Comi

unread,
Jan 29, 2013, 1:56:23 AM1/29/13
to pyth...@python.org
#! /usr/bin/python
    import numpy as np
    data = np.loadtxt('path-tracks.csv',dtype=np.str,delimiter=',',skiprows=1)
    print data
       
 [['19.70' '-95.20' '2/5/04 6:45 AM' '1' '-38' 'CCM']
 ['19.70' '-94.70' '2/5/04 7:45 AM' '1' '-48' 'CCM']
 ['19.30' '-93.90' '2/5/04 8:45 AM' '1' '-60' 'CCM']
 ['19.00' '-93.50' '2/5/04 9:45 AM' '1' '-58' 'CCM']
 ['19.00' '-92.80' '2/5/04 10:45 AM' '1' '-50' 'CCM']
 ['19.20' '-92.60' '2/5/04 11:45 AM' '1' '-40' 'CCM']
 ['19.90' '-93.00' '2/5/04 12:45 PM' '1' '-43' 'CCM']
 ['20.00' '-92.80' '2/5/04 1:15 PM' '1' '-32' 'CCM']
 ['23.10' '-100.20' '30/5/04 4:45 AM' '2' '-45' 'SCME']
 ['23.20' '-100.00' '30/5/04 5:45 AM' '2' '-56' 'SCME']
 ['23.30' '-100.00' '30/5/04 6:45 AM' '2' '-48' 'SCME']
 ['23.30' '-100.20' '30/5/04 7:45 AM' '2' '-32' 'SCME']
 ['23.40' '-99.00' '31/5/04 3:15 AM' '3' '-36' 'SCM']
 ['23.50' '-98.90' '31/5/04 4:15 AM' '3' '-46' 'SCM']
 ['23.60' '-98.70' '31/5/04 5:15 AM' '3' '-68' 'SCM']
 ['23.70' '-98.80' '31/5/04 6:15 AM' '3' '-30' 'SCM']]
 
Con el codigo de arriba, obtengo un arreglo cuyas columnas representan: [Lat, Lon, Date, Identifier, Temperatures, Category]. Ahora, con el codigo de abajo ploteo la primera y segunda columna sobre un mapa de México:
 
 

    #!/usr/bin/python
    #Project Storm: Plot trajectories of convective systems
    #import libraries
   
    import numpy as np
    from mpl_toolkits.basemap import Basemap
    import  matplotlib.pyplot as pl
   
    # Plot a map for Mexico
   
    m = Basemap(projection='cyl', llcrnrlat=12, urcrnrlat=35,llcrnrlon=-120, urcrnrlon=-80, resolution='c', area_thresh=1000.)
    m.bluemarble()
    m.drawcoastlines(linewidth=0.5)
    m.drawcountries(linewidth=0.5)
    m.drawstates(linewidth=0.5)
   
    #Draw parallels and meridians
   
    m.drawparallels(np.arange(10.,35.,5.))
    m.drawmeridians(np.arange(-120.,-80.,10.))
    m.drawmapboundary(fill_color='aqua')
   
    #Open file whit numpy
   
    data = np.loadtxt('path-tracks.csv', dtype=np.str,delimiter=' , ', skiprows=1)
    latitude = data[:,0]
    longitude = data[:,1]
   
    #Convert latitude and longitude to coordinates X and Y
   
    x, y = m(longitude, latitude)
   
    #Plot the points on the map
   
    pl.plot(x,y,'ro-')
    pl.show()

 

Los puntos graficados en el mapa, corresponden a tres diferentes trayectorias con una linea que conecta todos los puntos. MI idea es dibujar una linea que conecte los puntos asociados a cada trayectoria, como puedo lograr esto? o como debo estructurar mis datos para plotear las diferentes trayectorias?

es posible dibujar un identificador o una marca que me represente cada trayectoria?

como puedo configuar el tamaño de la figura para que pueda tener una mejor vista de las trayectorias?

Kiko

unread,
Jan 29, 2013, 2:48:40 AM1/29/13
to La lista de python en castellano


    #!/usr/bin/python
    #Project Storm: Plot trajectories of convective systems
    #import libraries
   
    import numpy as np
    from mpl_toolkits.basemap import Basemap
    import  matplotlib.pyplot as pl
   
    # Plot a map for Mexico
   
    m = Basemap(projection='cyl', llcrnrlat=12, urcrnrlat=35,llcrnrlon=-120, urcrnrlon=-80, resolution='c', area_thresh=1000.)
    m.bluemarble()
    m.drawcoastlines(linewidth=0.5)
    m.drawcountries(linewidth=0.5)
    m.drawstates(linewidth=0.5)
   
    #Draw parallels and meridians
   
    m.drawparallels(np.arange(10.,35.,5.))
    m.drawmeridians(np.arange(-120.,-80.,10.))
    m.drawmapboundary(fill_color='aqua')
   
    #Open file whit numpy
   
El código anterior es lo que quieres. A partir de aquí usaría:

data = np.array([['19.70','-95.20','2/5/04 6:45 AM','1','-38','CCM'],

['19.70','-94.70','2/5/04 7:45 AM','1','-48','CCM'],

['19.30','-93.90','2/5/04 8:45 AM','1','-60','CCM'],

['19.00','-93.50','2/5/04 9:45 AM','1','-58','CCM'],

['19.00','-92.80','2/5/04 10:45 AM','1','-50','CCM'],

['19.20','-92.60','2/5/04 11:45 AM','1','-40','CCM'],

['19.90','-93.00','2/5/04 12:45 PM','1','-43','CCM'],

['20.00','-92.80','2/5/04 1:15 PM','1','-32','CCM'],

['23.10','-100.20','30/5/04 4:45 AM','2','-45','SCME'],

['23.20','-100.00','30/5/04 5:45 AM','2','-56','SCME'],

['23.30','-100.00','30/5/04 6:45 AM','2','-48','SCME'],

['23.30','-100.20','30/5/04 7:45 AM','2','-32','SCME'],

['23.40','-99.00','31/5/04 3:15 AM','3','-36','SCM'],

['23.50','-98.90','31/5/04 4:15 AM','3','-46','SCM'],

['23.60','-98.70','31/5/04 5:15 AM','3','-68','SCM'],

['23.70','-98.80','31/5/04 6:15 AM','3','-30','SCM']])

latitude = data[:,0].astype(np.float)

longitude = data[:,1].astype(np.float)


## x, y no te hacen falta para nada en este contexto


#Plot the points on the map, puedes usar un for. En este caso son solo tres casos y lo pongo explícito.


pl.plot(longitude[data[:,3] == '1'], latitude[data[:,3] == '1'],'ro-') # El primer ¿sistema convectivo de mesoescala?

pl.plot(longitude[data[:,3] == '2'], latitude[data[:,3] == '2'],'yo-') # el segundo

pl.plot(longitude[data[:,3] == '3'], latitude[data[:,3] == '3'],'go-') # y el tercero

pl.show()


Para el tema de tamaños de figura y etiquetas en la trayectoria puedes echarle un ojo a:
http://pybonacci.wordpress.com/tag/tutorial-matplotlib-pyplot/

Si solo te interesa ver la zona de México donde suceden las tormentas, acótalo en:

m = Basemap(projection='cyl', llcrnrlat=12, urcrnrlat=35,llcrnrlon=-120, urcrnrlon=-80, resolution='c', area_thresh=1000.)

Saludos.

Juan Luis Cano

unread,
Jan 29, 2013, 2:49:15 AM1/29/13
to La lista de python en castellano
_______________________________________________
Python-es mailing list
Pyth...@python.org
http://mail.python.org/mailman/listinfo/python-es
FAQ: http://python-es-faq.wikidot.com/

Si reúnes en las variables x e y los valores de las tres trayectorias, naturalmente se mezclarán las tres en la representación. En primer lugar deberías separar las tres: tres variables latitude y tres variables longitude. ¿Por tus datos entiendo que la última columna es la que diferencia las tres?

lat_ccm = data[data[:, -1] == 'CCM', 0]
lon_ccm = data[data[:, -1] == 'CCM', 1]
lat_scme = data[data[:, -1] == 'SCME', 0]
lon_scme = data[data[:, -1] == 'SCME', 1]
lat_scm = data[data[:, -1] == 'SCM', 0]
lon_scm = data[data[:, -1] == 'SCM', 1]

Boris Vladimir Comi

unread,
Jan 29, 2013, 2:37:47 PM1/29/13
to La lista de python en castellano
Gracias por tomarte el tiempo en responder, ya estructure mis datos en la forma que me indicas y he obtneido el producuto deseado. Ahora mi preguntas es, si  mi archivo tiene mas de 30 trayectorias como las puedo graficar usando un for





De: Python-es [python-es-bounces+glez_b=comunida...@python.org] en nombre de Kiko [kikoco...@gmail.com]
Enviado: martes, 29 de enero de 2013 01:48 a.m.
Para: La lista de python en castellano
Asunto: Re: [Python-es] Dibujar trayectorias sobre un mapa usando matplotlib-basemap

Kiko

unread,
Jan 30, 2013, 3:01:18 AM1/30/13
to La lista de python en castellano
Hola, fíjate en qué es lo que cambia en las tres líneas de los plots anteriores. Cambia el número del caso/tormenta ('1', '2', '3') y el color de la línea para la trayectoria de la tormenta (r, y, g). Usa un for que recorra los posibles casos y usa colores diferentes para cada caso (http://matplotlib.org/api/colors_api.html) si quieres que tengan colores diferentes. Los posibles casos los puedes obtener usando un set. No te pongo el código de forma explícita para que lo pienses un poco. Si no eres capaz de conseguirlo vuelve a preguntar.

Saludos.

Boris Vladimir Comi

unread,
Feb 12, 2013, 2:43:16 PM2/12/13
to La lista de python en castellano

Thank you for your ideas, I leave the correct code to plot trajectories of any object, in my case I have drawn the trajectories of convective storms.

  1. # --- Construimos el mapa ---

  1. import numpy as np
  2. from mpl_toolkits.basemap import Basemap
  1. import matplotlib.pyplot as plt
  2. from PIL import *
  3. fig = plt.figure(figsize=(12,12))

  4. ax = fig.add_axes([0.1,0.1,0.8,0.8])

  1. m = Basemap(projection='cyl', llcrnrlat=12, urcrnrlat=35,llcrnrlon=-120, urcrnrlon=-80, resolution='c', area_thresh=1000.)

  2. m.bluemarble()
  3. m.drawcoastlines(linewidth=0.5)
  4. m.drawcountries(linewidth=0.5)
  5. m.drawstates(linewidth=0.5)

  1. # --- Dibujamos paralelos y meridianos ---

  2. m.drawparallels(np.arange(10.,35.,5.),labels=[1,0,0,1])
  3. m.drawmeridians(np.arange(-120.,-80.,5.),labels=[1,0,0,1])
  4. m.drawmapboundary(fill_color='aqua')

  5. # --- Abrimos el archivo que contiene los datos ---

  6. import pandas as pd

  7. df = pd.read_csv('scm-2004.csv')
  8. for evento, group in df.groupby(['evento']):
  9. latitude = group.lat.values
  10. longitude = group.lon.values
  11. x,y = m(longitude, latitude)
  12. plt.plot(x,y,'y-',linewidth=2 )
  13. plt.xlabel('Longitud')
  14. plt.ylabel('Latitud')
  15. plt.title('Trayectorias de Sistemas Convectivos 2004')



  16. plt.savefig('track-2004.jpg', dpi=100)

With the above code, I get the desired figure. 60 paths drawn on the map of México.

I have only one last question: how could indicate the start of each of the storms, someone has an idea how I can do this?

De: Python-es [python-es-bounces+glez_b=comunida...@python.org] en nombre de Kiko [kikoco...@gmail.com]
Enviado: miércoles, 30 de enero de 2013 02:01 a.m.

Kiko

unread,
Feb 13, 2013, 2:32:07 AM2/13/13
to La lista de python en castellano


2013/2/12 Boris Vladimir Comi <gle...@comunidad.unam.mx>

Una pregunta, ¿por qué hablas en inglés en la lista de python en español?

Respecto a tu pregunta, puedes dibujar solo el punto inicial de la trayectoria usando plt.plot o plt.scatter con x[0] e y[0] cambiando el color de ese punto o el marcador que se usa para la trayectoria teniendo un marcador diferente para el origen de la tormenta. Este plt.plot o plt. scatter deberías usarlo después del plt.plot que usas para la trayectoria completa para que se dibuje por encima de ella.

Saludos.

Boris Vladimir Comi

unread,
Feb 13, 2013, 8:54:56 AM2/13/13
to La lista de python en castellano
Antes que nada, perdon por escribir en ingles.


Gracias por la sugerencia, he logrado lo poner una marca al inicio de cada trayectoria.


Saludos

De: Python-es [python-es-bounces+glez_b=comunida...@python.org] en nombre de Kiko [kikoco...@gmail.com]
Enviado: miércoles, 13 de febrero de 2013 01:32 a.m.

Para: La lista de python en castellano
Asunto: Re: [Python-es] Dibujar trayectorias sobre un mapa usando matplotlib-basemap
Reply all
Reply to author
Forward
0 new messages