SkewT-logP-Diagramm mit Matplotlib

PythonPythonBeginner
Jetzt üben

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

💡 Dieser Artikel wurde von AI-Assistenten übersetzt. Um die englische Version anzuzeigen, können Sie hier klicken

Einführung

In diesem Lab lernen wir, wie man mithilfe der Matplotlib-Bibliothek in Python ein SkewT-logP-Diagramm erstellt. Ein SkewT-logP-Diagramm wird in der Meteorologie üblicherweise verwendet, um vertikale Temperaturprofile anzuzeigen. Es ist ein komplexer Plot, da es nicht-orthogonale X- und Y-Achsen umfasst. Wir werden die Transformations- und die benutzerdefinierte Projektions-API von Matplotlib verwenden, um diesen Plot zu erstellen.

Tipps für die virtuelle Maschine

Nachdem der Start der virtuellen Maschine abgeschlossen ist, klicken Sie in der oberen linken Ecke, um zur Registerkarte Notebook zu wechseln und Jupyter Notebook für die Übung zu nutzen.

Manchmal müssen Sie einige Sekunden warten, bis Jupyter Notebook vollständig geladen ist. Die Validierung von Vorgängen kann aufgrund der Einschränkungen von Jupyter Notebook nicht automatisiert werden.

Wenn Sie bei der Lernphase Probleme haben, können Sie Labby gerne fragen. Geben Sie nach der Sitzung Feedback, und wir werden das Problem für Sie prompt beheben.

Importieren der erforderlichen Bibliotheken

Wir beginnen mit dem Importieren der erforderlichen Bibliotheken. Für dieses Beispiel werden wir Matplotlib, NumPy und StringIO verwenden.

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)

Definieren der SkewXTick-Klasse

Die SkewXTick-Klasse wird verwendet, um die Markierungen auf dem SkewT-logP-Diagramm zu zeichnen. Sie überprüft, ob die Markierung auf der oberen oder unteren X-Achse gezeichnet werden muss, und setzt dementsprechend die Sichtbarkeit der Markierung und der Rasterlinie.

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

Definieren der SkewXAxis-Klasse

Die SkewXAxis-Klasse wird verwendet, um zwei separate Sets von Intervallen für die Markierungen bereitzustellen und Instanzen der benutzerdefinierten Markierung zu erstellen.

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]

Definieren der SkewSpine-Klasse

Die SkewSpine-Klasse berechnet den separaten Datenbereich der oberen X-Achse und zeichnet dort die Spur. Sie liefert auch diesen Bereich an den X-Achsen-Künstler für die Markierungen und die Rasterlinien.

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

Definieren der SkewXAxes-Klasse

Die SkewXAxes-Klasse behandelt die Registrierung der schrägen X-Achsen als Projection sowie die Einrichtung der entsprechenden Transformationen. Sie überschreibt die Standard-Spuren und Achsen-Instanzen entsprechend.

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]

Projection registrieren

Wir werden die Projection bei Matplotlib registrieren, damit wir sie in unserem Diagramm verwenden können.

register_projection(SkewXAxes)

Daten vorbereiten

Wir werden die Daten für unseren SkewT-logP-Diagramm vorbereiten. Wir werden das StringIO-Modul verwenden, um die Daten aus einem String zu lesen, und NumPy, um sie in Arrays zu laden.

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)

SkewT-logP-Diagramm erstellen

Wir werden nun das SkewT-logP-Diagramm mit der zuvor registrierten SkewXAxes-Projection erstellen. Zunächst werden wir ein Figure-Objekt erstellen und ein Subplot mit der SkewXAxes-Projection hinzufügen. Anschließend werden wir die Temperatur- und Taupunkt-Daten auf dem Diagramm mit der semilogy-Funktion plotten. Schließlich werden wir die Grenzen und Markierungen für die X- und Y-Achse festlegen und das Diagramm anzeigen.

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

Zusammenfassung

In diesem Lab haben wir gelernt, wie man ein SkewT-logP-Diagramm mit Matplotlibs Transformations- und benutzerdefinierter Projections-API erstellt. Wir haben eine SkewXTick-Klasse erstellt, um die Markierungen zu zeichnen, eine SkewXAxis-Klasse, um separate Intervalle für die Markierungen bereitzustellen, und eine SkewSpine-Klasse, um die Spur zu zeichnen. Wir haben auch eine SkewXAxes-Klasse erstellt, um die Transformationen und die Registrierung der SkewXAxes-Projection zu verwalten. Schließlich haben wir ein SkewT-logP-Diagramm erstellt, indem wir die Daten vorbereitet und auf dem SkewXAxes-Subplot geplottet haben.