Este artículo se actualizó el 2020/04/18 para usar las últimas versiones de las bibliotecas que se comentan.
Esto pretende ser un tutorial del módulo pyplot de la librería matplotlib. El tutorial lo dividiremos de la siguiente forma (que podrá ir cambiando a medida que vayamos avanzando).
- Primeros pasos
- Creando ventanas, manejando ventanas y configurando la sesión
- Configuración del gráfico
- Tipos de gráfico I
- Tipos de gráfico II
- Tipos de gráfico III
- Tipos de gráfico IV
- Texto y anotaciones (arrow, annotate, table, text…)
Herramientas estadísticas (acorr, cohere, csd, psd, specgram, spy, xcorr, …)Eventos e interactividad (connect, disconnect, ginput, waitforbuttonpress…)- Miscelánea
[Para este tutorial se ha usado python 3.7.6, ipython 7.13.0, numpy 1.17.2 y matplotlib 3.1.1, netcdf4-python 1.5.3 y basemap 1.3.0]
[DISCLAIMER: Muchos de los gráficos que vamos a representar no tienen ningún sentido físico y los resultados solo pretenden mostrar el uso de la librería].
En todo momento supondremos que se ha iniciado la sesión y se ha hecho:
1 2 3 4 |
import matplotlib.pyplot as plt import numpy as np import netCDF4 as nc from mpl_toolkits.basemap import Basemap as Bm |
Hasta ahora hemos visto como configurar las ventanas, manejo de las mismas, definir áreas de gráfico, algunos tipos de gráficos… Ahora vamos a ver un último capítulo sobre tipos de gráficos. En esta última entrada sobre los tipos de gráfico hemos metido gráficos que quizá no estén muy relacionados entre sí por lo que quizá este capítulo puede parecer un poco cajón desastre.
Anteriormente ya hemos usado Basemap, un toolkit que da capacidades de generar mapas a matplotlib. En este momento vamos a volver a recurrir a esta librería para mostrar datos sobre mapas. En el primer caso vamos a dibujar gráficos de barbas de viento (wind barbs) sobre un mapa. También vamos a usar la librería netcdf4-python, que permite leer, modificar y crear ficheros netcdf así como descargarlos desde diferentes TDS (servidores de datos THREDDS) de forma muy sencilla. Los datos que usaremos serán datos de viento obtenidos del reanálisis CFSR de la atmósfera pero podéis usar cualquier otro tipo de datos que se os ocurra. Descargad el fichero en este enlace y guardadlo en el mismo sitio donde estéis ejecutando el código.
1 2 3 |
plt.ion() # Ponemos el modo interactivo filename = 'splf06.gdas.2009120118.grb2.nc' # Ruta al fichero que usaremos datos = nc.Dataset(filename) # Accedemos a los datos |
Los datos corresponden a diciembre de 2009. Usaremos solo el campo de vientos que corresponde a las 00:00 UTC del 01/12/2009. Si ponéis en el prompt datos.variables
veréis un diccionario con las variables disponibles. Vamos a usar ‘u-component_of_wind_hybrid’, ‘v-component_of_wind_hybrid’, ‘lon’ y ‘lat’.
1 2 3 4 5 |
u = datos.variables['u-component_of_wind_hybrid'][0,0,:,:] # Guardamos en memoria el valor u del vector de viento para las 00:00 UTC del 01/12/2009 v = datos.variables['v-component_of_wind_hybrid'][0,0,:,:] # Guardamos en memoria el valor v del vector de viento para las 00:00 UTC del 01/12/2009 lon = datos.variables['lon'][:] # Guardamos los valores de longitud lat = datos.variables['lat'][:] # Guardamos los valores de latitud lons, lats = np.meshgrid(lon, lat) # Hacemos una malla regular 2D para las latitudes y las longitudes |
Una vez que disponemos de todas las variables pasamos a hacer el gráfico representando las barbas de viento. Como en diciembre hace mucho frío por Europa vamos a ver los vientos veraniegos que tuvimos en América Central y en América del sur durante en esa fecha.
1 2 3 4 5 6 |
m = Bm(llcrnrlon = 230, llcrnrlat = -60, urcrnrlon = 340, urcrnrlat = 38, projection = 'mill') # Definimos el área del gráfico y la proyección m.drawparallels(np.arange(-180,180,10),labels=[1,1,0,0]) # Dibujamos los paralelos m.drawmeridians(np.arange(0,360,10),labels=[0,0,0,1]) # Dibujamos los meridianos m.bluemarble() # Ponemos un mapa 'bonito' de fondo x, y = m(lons, lats) m.barbs(x[::8,::8],y[::8,::8],u[::8,::8],v[::8,::8],length=5,barbcolor='w',flagcolor='w',linewidth=0.5) # Y dibujamos los valores del vector viento |
El resultado quedaría de la siguiente forma:
Y un detalle de la parte sur:
El código completo del ejemplo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
import matplotlib.pyplot as plt import numpy as np import netCDF4 as nc from mpl_toolkits.basemap import Basemap as Bm plt.ion() # Ponemos el modo interactivo filename = 'splf06.gdas.2009120118.grb2.nc' # Ruta al fichero que usaremos datos = nc.Dataset(filename) # Accedemos a los datos u = datos.variables['u-component_of_wind_hybrid'][0,0,:,:] # Guardamos en memoria el valor u del vector de viento para las 00:00 UTC del 01/12/2009 v = datos.variables['v-component_of_wind_hybrid'][0,0,:,:] # Guardamos en memoria el valor v del vector de viento para las 00:00 UTC del 01/12/2009 lon = datos.variables['lon'][:] # Guardamos los valores de longitud lat = datos.variables['lat'][:] # Guardamos los valores de latitud lons, lats = np.meshgrid(lon, lat) # Hacemos una malla regular 2D para las latitudes y las longitudes m = Bm(llcrnrlon = 230, llcrnrlat = -60, urcrnrlon = 340, urcrnrlat = 38, projection = 'mill') # Definimos el área del gráfico y la proyección m.drawparallels(np.arange(-180,180,10),labels=[1,1,0,0]) # Dibujamos los paralelos m.drawmeridians(np.arange(0,360,10),labels=[0,0,0,1]) # Dibujamos los meridianos m.bluemarble() # Ponemos un mapa 'bonito' de fondo x, y = m(lons, lats) m.barbs(x[::8,::8],y[::8,::8],u[::8,::8],v[::8,::8],length=5,barbcolor='w',flagcolor='w',linewidth=0.5) # Y dibujamos los valores del vector viento |
En realidad no hemos usado ‘matplotlib.pyplot.barbs
‘ sino que hemos hecho uso de ‘barbs
‘ dentro de ‘basemap’ pero su uso es similar. Si no queréis dibujar barbas y queréis dibujar flechas echadle un ojo a matplotlib.pyplot.quiver
y a matplotlib.pyplot.quiverkey
(aquí tenéis ejemplos que os pueden ayudar http://matplotlib.github.com/basemap/users/examples.html).
Podéis encontrar muchos ejemplos de como usar matplotlib.pyplot
(en algunos casos usando pylab) en http://matplotlib.sourceforge.net/examples/pylab_examples/index.html.
Y, después de este breve entrada, hemos acabado por hoy y hemos acabado los tipos de gráfico que vamos a ver. Esto ha sido solo una muestra de las cosas que se suelen usar más. El próximo día veremos como hacer anotaciones en un gráfico. Si quieres ver las anteriores entregas del tutorial pulsa aquí.
Pingback: Bitacoras.com
Hola Juan Luis, excelente sitio gracias y felicitaciones por Tu esfuerzo y hacer posible . Repasé cada línea y funciona muy bien. Pero como se hace para guardar el valor del punto de grilla o pixel de por ejemplo lat-14 y lon 75 en un archivo txt. Y como le pongo en lugar de barbas de viento contraste de color e isolineas y su respectiva colorbar.
Saludos
Hola.
Por partes:
1) Soy Kiko, no Juanlu, 😛
2) lat, lon son vectores y lats, lons son arrays, de ellos puedes extraer los valores que quieras.
3) Para guardar la info en un fichero te recomiendo que empieces por lo básico: http://docs.python.org.ar/tutorial/3/inputoutput.html#leyendo-y-escribiendo-archivos
4) Para dibujar contornos le puedes echar un vistazo a http://pybonacci.org/2012/04/14/ejemplo-de-uso-de-basemap-y-netcdf4/
5) Para dibujar barras de colores puedes usar colorbar. Mira un ejemplo aquí: http://pybonacci.org/2012/07/01/manual-de-introduccion-a-matplotlib-pyplot-vi-tipos-de-grafico-iii/
Saludos.
Hola Kiko, tengo un problema, en el script usando otro tipo de datos, no encuentro el error. te agradeceria si alguien podria ayudar.
Saludos
P.S : mis datos tp://ftp.ifremer.fr/ifremer/cersat/products/gridded/MWF/L3/ASCAT/Daily//Netcdf/2017/11/29/2017112900_2017113000_daily-ifremer-L3-MWF-GLO-20171201105757-01.0.nc.bz2
import matplotlib.pyplot as plt
import numpy as np
import netCDF4 as nc
from netCDF4 import *
import numpy as np
from mpl_toolkits.basemap import Basemap as Bm
import matplotlib.pyplot as plt
#– open netcdf file
nc = Dataset(“/Users/Juan/Documents/python/2017112900_2017113000_daily-ifremer-L3-MWF-GLO-20171201105757-01.0.nc”, mode=’r’)
#– read variable
#var = nc.variables[‘wind_speed’][0,:,:]
#u10 = nc.variables[‘eastward_wind’][0,:,:,:]
u10 = nc.variables[‘eastward_wind’][0,:,:]
#v10 = nc.variables[‘northward_wind’][0,:,:]
v10 = nc.variables[‘northward_wind’][0,:,:]
#lat = nc.variables[‘latitude’][::-1]
lat = nc.variables[‘latitude’][:]
lon = nc.variables[‘longitude’][:]
lons, lats = np.meshgrid(lon, lat)
m = Bm(llcrnrlon = 240, llcrnrlat = -30, urcrnrlon = 300, urcrnrlat = 10, projection = ‘mill’) # Definimos el área del gráfico y la proyección
m.drawparallels(np.arange(-180,180,10),labels=[1,1,0,0]) # Dibujamos los paralelos
m.drawmeridians(np.arange(0,360,10),labels=[0,0,0,1]) # Dibujamos los meridianos
#m.bluemarble() # Ponemos un mapa ‘bonito’ de fondo
x, y = m(lons, lats)
m.barbs(x,y,u10[0,:,:],v10[0,:,:],length=5,barbcolor=’w’,flagcolor=’w’,linewidth=0.5) # Y dibujamos los valores del vector viento
#Q = plt.quiver(x,y,u10[0,:,:],v10[0,:,:],length=5,flagcolor=’w’,linewidth=0.5) # Y dibujamos los valores del vector viento
#Q = plt.quiver
#Q = plt.quiver
#m.barbs(vecplot, 0.2, -0.2, 20, ’20 m/s’, labelpos=’W’) #– position and reference label.
#vecplot = map.quiver(xx,yy,uproj,vproj,scale=600)
#plt.quiverkey(Q, 0.2, -0.2, 20, ’20 m/s’, labelpos=’W’) #– position and reference label.
#– display on screen
#plt.show()
#– maximize and save PNG file
#plt.savefig(‘plot_matplotlib_vector_on_contour_rect.png’, bbox_inches=’tight’, dpi=dpi)
Creo que estás leyendo mal los datos.
Te he dejado un ejemplo de cómo hacerlo usando Cartopy (Basemap se ha dejado de desarrollar y no se recomienda su uso):
https://gist.github.com/kikocorreoso/eeff69d4eaad35187d1d94a267beef8b
Saludos.
Genial Kiko!!!!
Saludos
¿como podría poner la escala del vector en los mapas ?
Hola.
La verdad es que Basemap ya no se actualizará más. Todo el esfuerzo se está yendo hacia CartoPy:
https://matplotlib.org/basemap/users/intro.html#cartopy-new-management-and-eol-announcement
Te recomiendo que uses CartoPy. Echa un ojo aquí:
https://stackoverflow.com/a/50674451