Intro a series de tiempo
TGRASS: GRASS Temporal
GRASS GIS es el primer SIG de código abierto que incorporó capacidades para gestionar, analizar, procesar y visualizar datos espacio-temporales, así como las relaciones temporales entre series de tiempo.
- Completamente basado en metadatos, por lo que no hay duplicación de datos
- Sigue una aproximación Snapshot, i.e., añade marcas de tiempo o timestamps a los mapas
- Una colección de mapas de la misma variable con timestamps se llama space-time dataset o STDS
- Los mapas en una STDS pueden tener diferentes extensiones espaciales y temporales
- TGRASS utiliza una base de datos SQLite para almacenar la extensión temporal y espacial de las STDS, así como las relaciones topológicas entre los mapas y entre las STDS en cada mapset.
TGRASS o GRASS GIS temporal framework fue desarrollado por Sören Gebbert como parte de un proyecto Google Summer of Code en 2012. Detalles técnicos de la implementación pueden encontrarse en: Gebbert y Pebesma (2014), Gebbert y Pebesma (2017) y Gebbert et al. (2019).
Space-time datasets
- Space time raster datasets (STRDS)
- Space time 3D raster datasets (STR3DS)
- Space time vector datasets (STVDS)
Otras nociones básicas en TGRASS
- El tiempo puede definirse como intervalos (inicio y fin) o como instancias (sólo inicio)
- El tiempo puede ser absoluto (por ejemplo, 2017-04-06 22:39:49) o relativo (por ejemplo, 4 años, 90 días)
- Granularidad es el mayor divisor común de todas las extensiones temporales (y posibles gaps) de los mapas de un STDS
- Topología se refiere a las relaciones temporales entre los intervalos de tiempo en una STDS
- Muestreo temporal se utiliza para determinar el estado de un proceso respecto un segundo proceso.
Módulos temporales
- t.*: Módulos generales para manejar STDS de todos los tipos
- t.rast.*: Módulos que tratan con STRDS
- t.rast3d.*: Módulos que tratan con STR3DS
- t.vect.*: Módulos que tratan con STVDS
TGRASS: marco general y flujo de trabajo
Manos a la obra
En esta segunda parte de la sesión vamos a recorrer los módulos temporales de GRASS GIS y demostrar su funcionalidad por medio de una serie de datos de temperatura de superficie (LST) de MODIS.
Antes de empezar y para ganar tiempo, conectamos nuestro drive e instalamos GRASS en Google Colab.
Datos para la sesión
- Producto MODIS: MOD11B3 Collection 6
- Tile: h12v12
- Composiciones mensuales
- Resolución espacial: 5600m
- Mapset
modis_lst
Iniciamos GRASS
Definimos las rutas y el mapset modis_lst
Importamos los paquetes de GRASS e iniciamos una sesión:
Región computacional y máscara
Listar los mapas raster y obtener información de uno de ellos
Vamos a agregar el semantic label a cada mapa de LST
Establecemos la región computacional
Aplicamos la máscara con los límites de la provincia de Córdoba
Crear un conjunto de datos espacio-temporales (STDS)
- Crea una tabla SQLite en la base de datos temporal
- Permite manejar grandes cantidades de mapas usando el STDS como entrada
- Necesitamos especificar:
- tipo de mapas (raster, raster3d o vector)
- tipo de tiempo (absoluto o relativo)
Creamos la STRDS
Chequear si la STRDS fue creada
Obtener información sobre la STRDS
Registrar mapas en una STDS (asignar timestamps)
- Asigna o agrega timestamps a los mapas
- Necesitamos:
- el STDS vacío como entrada, i.e., la tabla SQLite contenedora,
- la lista de mapas que se registrarán,
- la fecha de inicio,
- la opción de incremento junto con -i para la creación de intervalos
Chequear la información sobre la STRDS nuevamente
Revisamos la lista de mapas en la STRDS
Chequeamos los valores mínimos y máximos de cada mapa
Para más opciones sobre cómo registrar mapas, ver el manual de t.register y la wiki sobre opciones para registrar mapas en STDS.
Representación gráfica de STDS
Crear una representación gráfica de la serie de tiempo
Ver el manual de g.gui.timeline para más detalles.
Operaciones con álgebra temporal
- Realiza una amplia gama de operaciones de álgebra temporal y espacial basadas en la topología temporal de los mapas
- Operadores temporales: unión, intersección, etc.
- Funciones temporales: start_time(), start_doy(), etc.
- Operadores espaciales (subconjunto de r.mapcalc)
- Modificador de vecindario temporal: [x,y,t]
- Otras funciones temporales como t_snap(), buff_t() o t_shift()
¡pueden combinarse en expresiones complejas!
Desde K*50 a Celsius usando la calculadora temporal
Re-escalar a grados Celsius
Ver info de la nueva serie de tiempo
Gráfico temporal: LST vs tiempo
Gráfico temporal de LST para la ciudad de Córdoba, Argentina
En la interfaz de g.gui.tplot, las coordenadas del punto pueden ser escritas directamente, copiadas desde el mapa o seleccionadas interactivamente en el map display.
Para un único punto, ver g.gui.tplot. Para un vector de puntos, ver t.rast.what.
Listas y selecciones
- t.list para listar las STDS y los mapas registrados en la base de datos temporal,
- t.rast.list para mapas en series temporales de rasters, y
- t.vect.list para mapas en series temporales de vectores.
Variables usadas para hacer las listas y selecciones
STRDS: id, name, creator, mapset, temporal_type, creation_time, start_time, end_time, north, south, west, east, nsres, ewres, cols, rows, number_of_cells, min, max
STVDS: id, name, layer, creator, mapset, temporal_type, creation_time, start_time, end_time, north, south, west, east, points, lines, boundaries, centroids, faces, kernels, primitives, nodes, areas, islands, holes, volumes
Ejemplos de listas y selecciones
Mapas cuyo valor mínimo es menor o igual a 10
Mapas cuyo valor máximo es mayor a 30
Mapas contenidos entre dos fechas
Todos los mapas correspondientes al mes de Enero
Estadística descriptiva de STRDS
Imprimir estadísticas descriptivas univariadas para cada mapa dentro de la STRDS
Obtener estadísticas extendidas con la opción -e y escribir la salida a un archivo de texto
Graficamos las series del promedio, mínimo y máximo por mapa:
Agregación temporal 1: Serie completa
- Agrega STRDS completas o partes de ellas usando la opción where.
- Diferentes métodos disponibles: promedio, mínimo, máximo, mediana, moda, etc.
LST máxima y mínima del período 2015-2019
Obtener los mapas de la máxima y mínima LST del período
Cambiar la paleta de colores a celsius
Graficamos los mapas obtenidos
Usamos la calculadora de mapas temporal, t.rast.mapcalc,para obtener el mes de la LST mínima
Obtener información del mapa resultante
Obtenemos el primer mes en que aparece el mínimo de LST
Remover la STRDS intermedia y los mapas que contiene:
Chequeamos que la serie fue removida
Mostrar el mapa resultante con la clase Map de grass.jupyter
# display results
mm = gj.Map(width=450, use_region=True)
mm.d_rast(map="min_lst_date")
mm.d_vect(map="provincia_cba", type="boundary", color="#4D4D4D", width=2)
mm.d_legend(raster="min_lst_date", title="Month", fontsize=10, at=(2,15,2,10))
mm.d_barscale(length=50, units="kilometers", segment=4, fontsize=14, at=(73,7))
mm.d_northarrow(at=(90,15))
mm.d_text(text="Month of minimum LST", color="black", font="sans", size=4, bgcolor="white")
mm.show()Podríamos haber hecho lo mismo pero anualmente para conocer en qué mes ocurre el máximo en cada año y así evaluar la ocurrencia de tendencias. Cómo lo harían?
Agregación temporal 2: granularidad
- Agrega mapas raster dentro de STRDS con diferentes granularidades
- La opción where permite establecer fechas específicas para la agregación
- Diferentes métodos disponibles: promedio, mínimo, máximo, mediana, moda, etc.
De LST mensual a estacional
LST media estacional
Chequear info
Chequear lista de mapas
Establecer la paleta de colores celsius para la STRDS estacional
Mostramos la serie recientemente creada con una animación. Para eso vamos a usar la clase TimeSeriesMap de grass.jupyter
## Display newly created NDVI time series map
lstseries = gj.TimeSeriesMap(use_region=True)
lstseries.add_raster_series("LST_Day_mean_3month", fill_gaps=False)
lstseries.d_legend(color="black", at=(10,40,2,6))
lstseries.show() # Create TimeSlider
# optionally, write out to animated GIF
lstseries.save("lstseries.gif")Ahora que ya conocen t.rast.aggregate, extraigan el mes de máximo LST por año y luego vean si hay alguna tendencia positiva o negativa, es decir, si los valores máximos de LST se observan más tarde o más temprano con el tiempo (años).
Una solución podría ser…
Agregación vs Climatología
Climatologías mensuales
LST promedio de Enero
Climatología para todos los meses
- Comparar las medias mensuales con las climatologías mensuales
- Las climatologías que creamos forman una STRDS?
Anomalías anuales
Se necesitan:
- promedio y desviación estándar general de la serie
- promedios anuales
\[ AnomaliaStd_i = \frac{Media_i - Media}{SD} \]
Obtenemos primero el promedio y el desvío estándar general de la serie
y luego los promedios anuales
Utilizamos el álgebra temporal para estimar las anomalías anuales
Establecer la paleta de colores differences para toda la serie (esto permite tomar el minimo y maximo general de la serie)
Mostramos los resultados con una animación
Isla de calor superficial urbana (Surface Urban Heat Island - SUHI)
- La temperatura del aire de una zona urbana es más alta que la de las zonas cercanas
- La UHI tiene efectos negativos en la calidad del agua y el aire, la biodiversidad, la salud humana y el clima.
- La SUHI también está muy relacionada con la salud, ya que influye en la UHI
Estadística zonal en series de tiempo de datos raster
- Permite obtener datos de series de tiempo agregados espacialmente para polígonos de un mapa vectorial
SUHI estival para Córdoba y alrededores
Instalar la extensión v.strds.stats
Listar mapas
Extraer LST promedio de verano para el Gran Córdoba
Crear buffer externo - 30 km
Crear buffer interno - 15 km
Remover el área del buffer 15 km del buffer de 30 km
Extraer estadísticas para los alrededores del Gran Córdoba
Chequear la LST estival promedio para el Gran Córdoba y alrededores
# table massaging
df1 = tabla1.loc[1:,['cat', 'LST_Day_mean_3month_2015_02_01_average', 'LST_Day_mean_3month_2016_02_01_average', 'LST_Day_mean_3month_2017_02_01_average', 'LST_Day_mean_3month_2018_02_01_average', 'LST_Day_mean_3month_2019_02_01_average']]
df2 = tabla2.loc[1:,['cat', 'LST_Day_mean_3month_2015_02_01_average', 'LST_Day_mean_3month_2016_02_01_average', 'LST_Day_mean_3month_2017_02_01_average', 'LST_Day_mean_3month_2018_02_01_average', 'LST_Day_mean_3month_2019_02_01_average']]Se animan a hacer un gráfico de barras con librerías de Python para representar los valores promedios por año para la zona urbana y alrededores?
plt.figure(figsize=(10, 10))
g = sns.barplot(data= suhi_long, x="date", y="LST_Day_mean_3month_average", hue="setting")
g.set_xticklabels(["2015", "2016", "2017", "2018", "2019"])
plt.xlabel("Year")
plt.ylabel("LST Day mean 3month average")
sns.move_legend(g, "upper right", title= "Setting")
plt.show()