Introducción
En este laboratorio, aprenderemos a crear un diagrama SkewT-logP utilizando la biblioteca Matplotlib en Python. Un diagrama SkewT-logP se utiliza comúnmente en meteorología para mostrar perfiles verticales de temperatura. Es una representación compleja ya que implica ejes X e Y no ortogonales. Utilizaremos las transformaciones y la API de proyecciones personalizadas de Matplotlib para crear esta representación.
Consejos sobre la VM
Una vez finalizada la inicialización de la VM, haga clic en la esquina superior izquierda para cambiar a la pestaña Cuaderno y acceder a Jupyter Notebook para practicar.
A veces, es posible que tenga que esperar unos segundos a que Jupyter Notebook termine de cargarse. La validación de las operaciones no se puede automatizar debido a las limitaciones de Jupyter Notebook.
Si tiene problemas durante el aprendizaje, no dude en preguntar a Labby. Deje sus comentarios después de la sesión y lo resolveremos rápidamente para usted.
Importar las bibliotecas necesarias
Comenzaremos importando las bibliotecas necesarias. Para este ejemplo, usaremos Matplotlib, NumPy y StringIO.
from contextlib import ExitStack
from matplotlib.axes import Axes
import matplotlib.axis as maxis
from matplotlib.projections import register_projection
import matplotlib.spines as mspines
import matplotlib.transforms as transforms
import matplotlib.pyplot as plt
import numpy as np
from io import StringIO
from matplotlib.ticker import (MultipleLocator, NullFormatter, ScalarFormatter)
Definir la clase SkewXTick
La clase SkewXTick se utiliza para dibujar las marcas de graduación en el diagrama SkewT-logP. Verifica si la marca de graduación debe dibujarse en el eje X superior o inferior y, en consecuencia, establece la visibilidad de la marca de graduación y la línea de cuadrícula.
class SkewXTick(maxis.XTick):
def draw(self, renderer):
with ExitStack() as stack:
for artist in [self.gridline, self.tick1line, self.tick2line, self.label1, self.label2]:
stack.callback(artist.set_visible, artist.get_visible())
needs_lower = transforms.interval_contains(self.axes.lower_xlim, self.get_loc())
needs_upper = transforms.interval_contains(self.axes.upper_xlim, self.get_loc())
self.tick1line.set_visible(self.tick1line.get_visible() and needs_lower)
self.label1.set_visible(self.label1.get_visible() and needs_lower)
self.tick2line.set_visible(self.tick2line.get_visible() and needs_upper)
self.label2.set_visible(self.label2.get_visible() and needs_upper)
super().draw(renderer)
def get_view_interval(self):
return self.axes.xaxis.get_view_interval()
Definir la clase SkewXAxis
La clase SkewXAxis se utiliza para proporcionar dos conjuntos separados de intervalos a la marca de graduación y crear instancias de la marca de graduación personalizada.
class SkewXAxis(maxis.XAxis):
def _get_tick(self, major):
return SkewXTick(self.axes, None, major=major)
def get_view_interval(self):
return self.axes.upper_xlim[0], self.axes.lower_xlim[1]
Definir la clase SkewSpine
La clase SkewSpine calcula el rango de datos separado del eje X superior y dibuja la espina allí. También proporciona este rango al artista del eje X para la marcas de graduación y las líneas de cuadrícula.
class SkewSpine(mspines.Spine):
def _adjust_location(self):
pts = self._path.vertices
if self.spine_type == 'top':
pts[:, 0] = self.axes.upper_xlim
else:
pts[:, 0] = self.axes.lower_xlim
Definir la clase SkewXAxes
La clase SkewXAxes maneja el registro de los ejes x inclinados como una proyección, así como la configuración de las transformaciones adecuadas. Sobrescribe las instancias estándar de espinas y ejes según sea necesario.
class SkewXAxes(Axes):
name ='skewx'
def _init_axis(self):
super()._init_axis()
self.xaxis = SkewXAxis(self)
self.spines.top.register_axis(self.xaxis)
self.spines.bottom.register_axis(self.xaxis)
def _gen_axes_spines(self):
spines = {'top': SkewSpine.linear_spine(self, 'top'),
'bottom': mspines.Spine.linear_spine(self, 'bottom'),
'left': mspines.Spine.linear_spine(self, 'left'),
'right': mspines.Spine.linear_spine(self, 'right')}
return spines
def _set_lim_and_transforms(self):
super()._set_lim_and_transforms()
rot = 30
self.transDataToAxes = (self.transScale + self.transLimits + transforms.Affine2D().skew_deg(rot, 0))
self.transData = self.transDataToAxes + self.transAxes
self._xaxis_transform = (transforms.blended_transform_factory(
self.transScale + self.transLimits, transforms.IdentityTransform()) + transforms.Affine2D().skew_deg(rot, 0) + self.transAxes)
@property
def lower_xlim(self):
return self.axes.viewLim.intervalx
@property
def upper_xlim(self):
pts = [[0., 1.], [1., 1.]]
return self.transDataToAxes.inverted().transform(pts)[:, 0]
Registrar la proyección
Registraremos la proyección con Matplotlib para que podamos utilizarla en nuestra gráfica.
register_projection(SkewXAxes)
Preparar los datos
Prepararemos los datos para nuestro diagrama SkewT-logP. Utilizaremos el módulo StringIO para leer los datos de una cadena y NumPy para cargarlos en matrices.
data_txt = '''
978.0 345 7.8 0.8
971.0 404 7.2 0.2
946.7 610 5.2 -1.8
...
'''
sound_data = StringIO(data_txt)
p, h, T, Td = np.loadtxt(sound_data, unpack=True)
Crear el diagrama SkewT-logP
Ahora crearemos el diagrama SkewT-logP utilizando la proyección SkewXAxes que registramos anteriormente. Primero crearemos un objeto de figura y agregaremos un subgráfico con la proyección SkewXAxes. Luego graficaremos los datos de temperatura y punto de rocío en el diagrama utilizando la función semilogy. Finalmente, estableceremos los límites y las marcas de graduación para los ejes X e Y y mostraremos la gráfica.
fig = plt.figure(figsize=(6.5875, 6.2125))
ax = fig.add_subplot(projection='skewx')
ax.semilogy(T, p, color='C3')
ax.semilogy(Td, p, color='C2')
ax.axvline(0, color='C0')
ax.yaxis.set_major_formatter(ScalarFormatter())
ax.yaxis.set_minor_formatter(NullFormatter())
ax.set_yticks(np.linspace(100, 1000, 10))
ax.set_ylim(1050, 100)
ax.xaxis.set_major_locator(MultipleLocator(10))
ax.set_xlim(-50, 50)
plt.grid(True)
plt.show()
Resumen
En este laboratorio, aprendimos cómo crear un diagrama SkewT-logP utilizando las transformaciones de Matplotlib y la API de proyección personalizada. Creamos una clase SkewXTick para dibujar las marcas de graduación, una clase SkewXAxis para proporcionar intervalos separados para las marcas de graduación y una clase SkewSpine para dibujar la espina. También creamos una clase SkewXAxes para manejar las transformaciones y el registro de la proyección SkewXAxes. Finalmente, creamos un diagrama SkewT-logP preparando los datos y graficándolos en el subgráfico SkewXAxes.