Continuando lo que enseñó Juanlu en la anterior entrada vamos a mostrar líneas de nivel y temperatura del aire en la superficie, en este caso la presión al nivel del mar del día 01 de enero de 2012 a las 00.00 UTC según los datos extraídos del reanálisis NCEP/NCAR, sobre un mapa con la ayuda de la librería Basemap. Como los datos del reanálisis NCEP/NCAR vienen en formato netCDF usaremos la librería netcdf4-python. El formato netCDF es un estándar abierto y es ampliamente usado en temas de ciencias de la tierra, atmósfera, climatología, meteorología,... No es estrictamente necesario usar netcdf4-python para acceder a ficheros netCDF puesto que desde scipy tenéis esta funcionalidad. Pero bueno, yo uso esta por una serie de ventajas que veremos otro día. En la presente entrada se ha usado python 2.7.2, numpy 1.6.1, matplotlib 1.1.0, netCDF4 0.9.7 y Basemap 1.0.2. Primero de todo vamos a importar todo lo que necesitamos: [sourcecode language="python"] ## Importamos las librerías que nos hacen falta import numpy as np import netCDF4 as nc import matplotlib.pyplot as plt from mpl_toolkits import basemap as bm [/sourcecode] Los ficheros netCDF de presión al nivel del mar y de Temperatura del aire de la superficie los podéis descargar de aquí y aquí, respectivamente. Veréis un enlace que pone 'FTP a copy of the file', lo pincháis y guardáis en el mismo sitio donde tengáis el script que estamos haciendo en la presente entrada. Una vez que tenemos los ficheros los podemos abrir usando la librería netCDF4-python: [sourcecode language="python"] ## Abrimos los ficheros de datos, ## el nombre de los ficheros lo tendréis que cambiar ## con el nombre de los ficheros que os habéis descargado slp = nc.Dataset('X83.34.8.250.104.4.18.19.nc') #slp por 'sea level pressure' tsfc = nc.Dataset('X83.34.8.250.104.4.15.31.nc') #tsfc 'por temperature at surface' [/sourcecode]
Para saber las variables que tenemos en cada fichero netCDF podemos escribir lo siguiente: [sourcecode language="python"] ## Qué variables hay dentro de cada netCDF print slp.variables print tsfc.variables [/sourcecode] El output que veremos para slp será: [sourcecode language="python"] OrderedDict([(u'lat',
En el anterior mapa hemos mostrado las líneas de nivel de la presión, hemos dibujado meridianos y paralelos y lo hemos representado con una proyección cilíndrica de Miller usando como fondo los datos Blue Marble de la NASA. Ahora vamos a introducir también los datos de temperatura usando contourf (la f viene de fill, relleno y son contornos rellenados). Metemos lo siguiente en nuestro script: [sourcecode language="python"] # create figure. fig=plt.figure(figsize=(8,6)) ax = fig.add_axes([0.05,0.05,0.9,0.85]) cs = m.contour(x,y,slpdata[0,:,:],np.arange(900,1100.,5.),colors='k',linewidths=1.) csf = m.contourf(x,y,tsfcdata[0,:,:],np.arange(-50,50.,2.)) m.drawcoastlines(linewidth=1.25, color='grey') m.drawparallels(np.arange(0,360,10),labels=[1,1,0,0]) m.drawmeridians(np.arange(-180,180,10),labels=[0,0,0,1]) plt.show() [/sourcecode] Y obtenemos el siguiente resultado:
Donde hemos representado la presión al nivel del mar (isolíneas en color negro), las temperaturas en superficie (contornos de color rellenos), las líneas de costa (líneas continuas grises), paralelos y meridianos. El script final quedaría algo así: [sourcecode language="python"] ## Importamos las librerías que vamos a usar import numpy as np import netCDF4 as nc import matplotlib.pyplot as plt from mpl_toolkits import basemap as bm ## Abrimos los ficheros de datos slp = nc.Dataset('X83.34.8.250.104.4.18.19.nc') #slp por 'sea level pressure' tsfc = nc.Dataset('X83.34.8.250.104.4.15.31.nc') #tsfc 'por temperature at surface'slp.variables print slp.variables print tsfc.variables slpdata = slp.variables['slp'][:] #Obtenemos los datos en Pa tsfcdata = tsfc.variables['air'][:] #Obtenemos los datos en ºK lat = slp.variables['lat'][:] #Obtenemos los datos en º lon = slp.variables['lon'][:] #Obtenemos los datos en º slpdata = slpdata * 0.01 tsfcdata = tsfcdata - 273.15 lon[lon > 180] = lon - 360. ## Creamos una instancia a Basemap m = bm.Basemap(llcrnrlon = -20, llcrnrlat = 25, urcrnrlon = 60, urcrnrlat = 80, projection = 'mill') print bm.supported_projections ## Encontramos los valores x,y para el grid de la proyección del mapa. lon, lat = np.meshgrid(lon, lat) x, y = m(lon, lat) # Creamos la figura con P sobre fondo Blue Marble. fig=plt.figure(figsize=(8,6)) ax = fig.add_axes([0.05,0.05,0.9,0.85]) cs = m.contour(x,y,slpdata[0,:,:],np.arange(900,1100.,5.),colors='y',linewidths=1.25) m.drawparallels(np.arange(0,360,10),labels=[1,1,0,0]) m.drawmeridians(np.arange(-180,180,10),labels=[0,0,0,1]) m.bluemarble() plt.show() # Creamos la figura con P y T. fig=plt.figure(figsize=(8,6)) ax = fig.add_axes([0.05,0.05,0.9,0.85]) cs = m.contour(x,y,slpdata[0,:,:],np.arange(900,1100.,5.),colors='k',linewidths=1.) csf = m.contourf(x,y,tsfcdata[0,:,:],np.arange(-50,50.,2.)) m.drawcoastlines(linewidth=1.25, color='grey') m.drawparallels(np.arange(0,360,10),labels=[1,1,0,0]) m.drawmeridians(np.arange(-180,180,10),labels=[0,0,0,1]) plt.show() [/sourcecode] Y eso es todo por hoy. En algún momento, siempre que el tiempo lo permita, veremos más en profundidad Basemap y Netcdf4-python. Saludos. P.D.: Lo de siempre, si encontráis errores, queréis criticar (constructivamente) mis bajas dotes como programador o queréis aportar alguna cosa usad los comentarios.
Pybonacci