# visualizacion-geospacial-avanzada-con-pygmt
Visualización Geospacial Avanzada con PyGMT
Volver a la portada del cursoTécnicas Avanzadas de Visualización
Sección 3 · Visualizaciones de Datos Avanzados
Técnicas avanzadas de visualización con PyGMT
Un mapa de costas es el punto de partida. Los mapas que comunican de verdad combinan varias capas: una grilla de relieve con sombreado, una paleta de colores con su escala, curvas de nivel, datos puntuales codificados por color y tamaño, y un mapa de ubicación. Esta lección recorre esas técnicas con los datos de relieve de GMT.
Grillas y paletas de color
Una grilla es una tabla de valores sobre una malla regular de longitudes y latitudes; en PyGMT es un xarray.DataArray. fig.grdimage la convierte en una imagen, y la paleta (CPT, color palette table) decide qué color recibe cada valor. pygmt.makecpt crea la paleta activa a partir de un mapa de colores y un rango:
geoyetopo1están pensadas para relieve: azules bajo el mar y verdes, ocres y blancos en tierra.viridis,batlowolajollason perceptualmente uniformes: el cambio de color es proporcional al cambio de valor, también en escala de grises.pygmt.grd2cptcalcula el rango directamente de la grilla, útil cuando no conoces sus valores.
Sombreado: el relieve en tres dimensiones aparentes
El sombreado simula una luz que ilumina el terreno desde un ángulo. pygmt.grdgradient calcula la pendiente en la dirección de la luz (el acimut), y ese gradiente se pasa a grdimage en el parámetro shading. El acimut 315 (luz desde el noroeste) es la convención cartográfica, porque así el ojo interpreta las montañas como elevaciones y no como valles:
import pygmt
region = [-118, -86, 14, 33]
grid = pygmt.datasets.load_earth_relief(resolution="05m", region=region)
sombra = pygmt.grdgradient(grid=grid, azimuth=315, normalize="e0.6")
fig = pygmt.Figure()
pygmt.makecpt(cmap="geo", series=[-5000, 4000])
fig.grdimage(grid=grid, shading=sombra, projection="M15c",
frame=["af", "+tRelieve de México"], cmap=True)
fig.coast(shorelines="0.4p,black", borders="1/0.6p,white")
fig.colorbar(frame=["a2000", "x+lElevación", "y+lm"])
fig.savefig("relieve.png")
normalize="e0.6" normaliza el gradiente con una función acumulada y lo escala a ±0.6: valores altos dan más contraste; valores bajos, un sombreado sutil.
Curvas de nivel
fig.grdcontour dibuja isolíneas sobre la grilla. levels fija el intervalo entre curvas y annotation, cada cuántos metros se escribe el valor. Úsalas con moderación: sobre un relieve ya coloreado, pocas curvas finas aportan más que muchas gruesas.
import pygmt
grid = pygmt.datasets.load_earth_relief(resolution="05m", region=[-100, -96, 18, 20.5])
fig = pygmt.Figure()
fig.grdimage(grid=grid, projection="M12c", cmap="geo", frame="af")
fig.grdcontour(grid=grid, levels=500, annotation=1000, pen="0.3p,black")
fig.savefig("contornos.png")
Datos puntuales: color y tamaño
Los sismos son el ejemplo perfecto de datos puntuales con dos atributos. Con fig.plot puedes codificar la profundidad con el color y la magnitud con el tamaño. El estilo "cc" indica círculos con el diámetro en centímetros tomado de la columna size:
import pygmt
sismos = pygmt.datasets.load_sample_data("usgs_quakes")
mx = sismos[sismos.longitude.between(-118, -86) & sismos.latitude.between(14, 33)]
fig = pygmt.Figure()
fig.coast(region=[-118, -86, 14, 33], projection="M15c", land="gray90",
water="lightblue", frame="af")
pygmt.makecpt(cmap="lajolla", series=[0, 150])
fig.plot(x=mx.longitude, y=mx.latitude, size=0.02 * 2 ** (mx.mag - 3),
fill=mx.depth, cmap=True, style="cc", pen="0.2p,black")
fig.colorbar(frame="af+lProfundidad (km)")
fig.savefig("sismos.png")
La magnitud es logarítmica, por eso el tamaño crece como potencia de 2: un sismo un punto más fuerte se dibuja con el doble de diámetro.
Mapas de ubicación, leyendas y textos
Un mapa regional gana contexto con un recuadro (inset) que muestra dónde está la región en el mundo. fig.inset abre un bloque donde todo lo que dibujas cae dentro del recuadro. Con dcw resaltas un país por su código ISO. Las etiquetas se agregan con fig.text y la leyenda se construye con el argumento label de cada capa:
import pygmt
fig = pygmt.Figure()
fig.coast(region=[-118, -86, 14, 33], projection="M12c", land="gray",
water="lightblue", frame=True)
fig.plot(x=[-99.13], y=[19.43], style="c0.3c", fill="red",
pen="black", label="Ciudad de México")
fig.text(x=-99.13, y=20.2, text="CDMX", font="10p,Helvetica-Bold")
fig.legend(position="jBL+o0.2c", box=True)
with fig.inset(position="jTR+w3.5c+o0.2c", box="+pblack"):
fig.coast(region="g", projection="G-100/20/3.5c", land="gray",
water="white", dcw="MX+gred")
fig.savefig("ubicacion.png")
Vista en perspectiva
fig.grdview dibuja la grilla como una superficie 3D. perspective=[acimut, elevación] fija el punto de vista y zsize, la altura de la caja vertical. Pasa siempre region con los límites de la grilla.
import pygmt
region = [-100, -97, 18, 20]
grid = pygmt.datasets.load_earth_relief(resolution="02m", region=region)
fig = pygmt.Figure()
fig.grdview(grid=grid, region=region, perspective=[135, 30],
projection="M12c", zsize="3c", surftype="s", cmap="geo",
shading=True, frame=["xaf", "yaf", "zaf+lm"])
fig.savefig("perspectiva.png")
Trampas comunes
- Paletas tipo arcoíris (
jet,rainbow). Crean bordes visuales que no existen en los datos; prefiere paletas perceptualmente uniformes. - Escala de color sin unidades. Toda
colorbarnecesita su etiqueta con unidades. - Sombreado excesivo. Con
normalizemayor a 1 el sombreado tapa los colores; empieza en 0.5. - Omitir
regionengrdview. La superficie puede quedar diminuta dentro de una caja enorme. - Nombres de parámetros obsoletos. En PyGMT 0.18 algunos parámetros cambiaron de nombre (por ejemplo,
margindeinsetpasó aclearance); si ves unFutureWarning, actualiza el nombre.
Cierre
Construye cada mapa capa por capa y revisa el resultado después de cada una: grilla, sombreado, curvas, datos, contexto y escala. Si una capa no aporta información, quítala.