Diagramme SkewT-logP utilisant Matplotlib

PythonPythonBeginner
Pratiquer maintenant

This tutorial is from open-source community. Access the source code

💡 Ce tutoriel est traduit par l'IA à partir de la version anglaise. Pour voir la version originale, vous pouvez cliquer ici

Introduction

Dans ce laboratoire, nous allons apprendre à créer un diagramme SkewT-logP à l'aide de la bibliothèque Matplotlib en Python. Un diagramme SkewT-logP est couramment utilisé en météorologie pour afficher les profils verticaux de température. C'est un tracé complexe car il implique des axes X et Y non orthogonaux. Nous utiliserons les transformations et l'API de projection personnalisée de Matplotlib pour créer ce tracé.

Conseils sur la machine virtuelle

Une fois le démarrage de la machine virtuelle terminé, cliquez dans le coin supérieur gauche pour basculer vers l'onglet Carnet de notes pour accéder au carnet Jupyter Notebook pour pratiquer.

Parfois, vous devrez peut-être attendre quelques secondes pour que le carnet Jupyter Notebook ait fini de charger. La validation des opérations ne peut pas être automatisée en raison des limites du carnet Jupyter Notebook.

Si vous rencontrez des problèmes pendant l'apprentissage, n'hésitez pas à demander à Labby. Donnez votre feedback après la session, et nous résoudrons rapidement le problème pour vous.

Importation des bibliothèques requises

Nous commencerons par importer les bibliothèques requises. Pour cet exemple, nous utiliserons Matplotlib, NumPy et 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)

Définir la classe SkewXTick

La classe SkewXTick est utilisée pour tracer les graduations sur le diagramme SkewT-logP. Elle vérifie si la graduation doit être dessinée sur l'axe X supérieur ou inférieur et règle en conséquence la visibilité de la graduation et de la ligne de grille.

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()

Définir la classe SkewXAxis

La classe SkewXAxis est utilisée pour fournir deux ensembles distincts d'intervalles aux graduations et créer des instances de la graduation personnalisée.

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]

Définir la classe SkewSpine

La classe SkewSpine calcule la plage de données séparée de l'axe X supérieur et dessine l'arête à cet emplacement. Elle fournit également cette plage à l'artiste de l'axe X pour les graduations et les lignes de grille.

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

Définir la classe SkewXAxes

La classe SkewXAxes gère l'enregistrement des axes en diagonale comme une projection ainsi que la configuration des transformations appropriées. Elle remplace les instances d'arêtes et d'axes standards en conséquence.

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]

Enregistrer la projection

Nous allons enregistrer la projection avec Matplotlib afin que nous puissions l'utiliser dans notre tracé.

register_projection(SkewXAxes)

Préparer les données

Nous allons préparer les données pour notre diagramme SkewT-logP. Nous utiliserons le module StringIO pour lire les données à partir d'une chaîne de caractères et NumPy pour les charger dans des tableaux.

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)

Créer le diagramme SkewT-logP

Nous allons maintenant créer le diagramme SkewT-logP en utilisant la projection SkewXAxes que nous avons enregistrée précédemment. Nous allons tout d'abord créer un objet figure et ajouter un sous-graphique avec la projection SkewXAxes. Nous tracerons ensuite les données de température et de point de rosée sur le diagramme en utilisant la fonction semilogy. Enfin, nous définirons les limites et les graduations pour l'axe X et l'axe Y et afficherons le tracé.

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()

Sommaire

Dans ce laboratoire, nous avons appris à créer un diagramme SkewT-logP en utilisant les transformations de Matplotlib et l'API de projection personnalisée. Nous avons créé une classe SkewXTick pour tracer les graduations, une classe SkewXAxis pour fournir des intervalles séparés pour les graduations et une classe SkewSpine pour tracer l'arête. Nous avons également créé une classe SkewXAxes pour gérer les transformations et l'enregistrement de la projection SkewXAxes. Enfin, nous avons créé un diagramme SkewT-logP en préparant les données et en les traçant sur le sous-graphique SkewXAxes.