Unidata Logo

Upper Air and the Skew-T Log-P

Unidata Python Workshop


Example Skew-T

Overview:

  • Teaching: 30 minutes
  • Exercises: 60 minutes

Questions

  1. Where can upper air data be found and what format is it in?
  2. How can I obtain upper air data programatically?
  3. How can MetPy be used to make a Skew-T Log-P diagram?
  4. What calculations can be performed on the data?

Objectives

  1. Obtain upper air data
  2. Make a simple plot
  3. Make a Skew-T
  4. Calculate LCL, LFC, EL
  5. Parcel Path
  6. Calculate CAPE and CIN
  7. Other parameters
  8. Adding fiducial lines and shading
  9. Plotting a hodograph

Obtain upper air data

Upper air observations are reported as a plain text file in a tabular format that represents the down sampled raw data transmitted by the balloon. Data are reported an mandatory levels and at levels of significant change. An example of the beginning of sounding data may look like this:

-----------------------------------------------------------------------------
   PRES   HGHT   TEMP   DWPT   RELH   MIXR   DRCT   SKNT   THTA   THTE   THTV
    hPa     m      C      C      %    g/kg    deg   knot     K      K      K 
-----------------------------------------------------------------------------
 1000.0    270                                                               
  991.0    345   -0.3   -2.8     83   3.15      0      0  273.6  282.3  274.1
  984.0    403   10.2   -7.8     27   2.17    327      4  284.7  291.1  285.0
  963.0    581   11.8   -9.2     22   1.99    226     17  288.0  294.1  288.4
  959.7    610   11.6   -9.4     22   1.96    210     19  288.1  294.1  288.5

The data are available to download from the University of Wyoming archive, the Iowa State archive, and the Integrated Global Radiosonde Archive (IGRA). There is no need to download data manually. We can use the siphon library (also developed at Unidata) to request and download these data. Let's download some data from Miami just prior to Irma's landfall.

First, we need to create a datetime object that has the time of observation we are looking for. We can then request the data for a specific station. Currently date range requests are not possible, but planned for future releases.

In [ ]:
from datetime import datetime

from siphon.simplewebservice.wyoming import WyomingUpperAir

date = datetime(2017, 9, 10, 6)
station = 'MFL'
df = WyomingUpperAir.request_data(date, station)

The data are returned as a pandas DataFrame:

In [ ]:
df

Next, we will pull out the data and attach the units which are stored in a dictionary in the DataFrame attribute units.

In [ ]:
from metpy.units import pandas_dataframe_to_unit_arrays, units

data = pandas_dataframe_to_unit_arrays(df)
EXERCISE:
  • Get data from the 9/10/2017 00Z Key West sounding (the one closest to Irma's landfall). Use the Wyoming webpage or SPC sounding analysis page if you need to lookup the station identifier.
  • Attach data to the units and assign it to the data variable.
In [ ]:
# Your code goes here

df = WyomingUpperAir.request_data(datetime(2017, 9, 10, 0), 'KEY')
data = pandas_dataframe_to_unit_arrays(df)

Top


Make a Simple Plot

Knowing what we already know about plotting in Python, we can explore the data a little, but the plots are not exactly what we are used to looking at. (Also notice that if we do not provide unit labels, matplotlib will work with the units attached to the quantities!

In [ ]:
import matplotlib.pyplot as plt
%matplotlib inline
In [ ]:
fig = plt.figure(figsize=(10, 10))
ax1 = plt.subplot()

ax1.plot(data['temperature'], data['pressure'], color='tab:red')
ax1.plot(data['dewpoint'], data['pressure'], color='blue')

ax1.set_ylim(1000, 0)

Top


Make a Skew-T

As meteorologists, we are used to looking at soundings on the Skew-T Log-p diagram. This is a tricky plot to make – the isotherms are skewed diagonally, pressure is plotted in log space, and we often want to see fiducial lines showing dry adiabats, moist adiabats, etc. MetPy has the capability to make a Skew-T baked in!

In [ ]:
from metpy.plots import SkewT

# Create a new figure. The dimensions here give a good aspect ratio
fig = plt.figure(figsize=(10, 10))
skew = SkewT(fig)

# Plot the data using normal plotting functions, all of the transforms
# happen in the background!
skew.plot(data['pressure'], data['temperature'], color='tab:red')

Let's set the pressure limits to be sensible for what we're interested in, say 1000-100 hPa. We'll also add wind barbs using the plot_barbs functionality from metpy.

Tip: You can redisplay the same figure after we've modified it by simply putting the figure handle at the bottom of the cell.
In [ ]:
# Add wind barbs
skew.plot_barbs(data['pressure'], data['u_wind'], data['v_wind'])

# Set some sensible axis limits
skew.ax.set_ylim(1000, 100)

fig
EXERCISE:
  • Add a blue line for dewpoint.
  • Set the x-axis limits to something sensible.
In [ ]:
# Your code goes here

skew.plot(data['pressure'], data['dewpoint'], color='blue')
skew.ax.set_xlim(-40, 60)

fig

Top


Calculate LCL, LFC, EL

Generally we are interested in some thermodynamic parameters when looking at upper air data. We often want to know what the level of free convection (LFC), the lifted condensation level (LCL), or the equilibrium level (EL) is for a given sounding. MetPy implements these calculations for you, taking care of the numerical methods and testing. Let’s calculate some of these values and add them to our Skew-T.

In [ ]:
import metpy.calc as mpcalc

lcl_pressure, lcl_temperature = mpcalc.lcl(data['pressure'][0],
                                           data['temperature'][0],
                                           data['dewpoint'][0])
In [ ]:
# Only try to draw the line if the value isn't NaN!
if lcl_pressure:
    skew.ax.axhline(lcl_pressure, color='black')

fig
EXERCISE:
  • Add the LFC to the plot (lfc takes the pressure, temperature, and dewpoint profiles).
  • Add the EL to the plot.
In [ ]:
# Your code goes here

# Calculate the LFC and plot it if it exists
lfc_pressure, lfc_temperature = mpcalc.lfc(data['pressure'], data['temperature'], data['dewpoint'])

if lfc_pressure:
    skew.ax.axhline(lfc_pressure, color='tab:brown')

# Calculate the EL and plot it if it exists
el_pressure, el_temperature = mpcalc.el(data['pressure'], data['temperature'], data['dewpoint'])

if el_pressure:
    skew.ax.axhline(el_pressure, color='tab:blue')

fig

Top


Parcel Path

When considering the stability of the atmosphere we often talk about the ideal parcel path. A parcel lifted from the surface along a dry adiabatic path until it becomes saturated, then lifted along a moist adiabatic path. MetPy will calculated the ideal parcel path given the starting point (generally the surface).

In [ ]:
parcel_path = mpcalc.parcel_profile(data['pressure'],
                                    data['temperature'][0],
                                    data['dewpoint'][0]).to('degC')
In [ ]:
print(parcel_path)
In [ ]:
skew.plot(data['pressure'], parcel_path, color='black')
fig

Top


Calculate CAPE and CIN

Some of the most requested thermodynamic parameters are the Convective Available Potential Energy (CAPE) and Convective INhibition (CIN). MetPy will allow you to compute these in a single call!

In [ ]:
mpcalc.surface_based_cape_cin(data['pressure'], data['temperature'], data['dewpoint'])
EXERCISE:
  • Calculate the most unstable CAPE/CIN for this sounding. What do you expect the results to be?

HINT: Look at the documentation for most_unstable_cape_cin.

In [ ]:
# Your code goes here

mpcalc.most_unstable_cape_cin(data['pressure'], data['temperature'], data['dewpoint'])
TIP: You can calculate CAPE and CIN with any parcel profile you can dream up! This allows you to play with the surface conditions, mix layers, or use different adiabatic profiles. The function cape_cin takes an arbitrary parcel as its last argument.

Top


Other Parameters

There are several other parameters you can calculate with MetPy. These include bulk shear, Bunkers storm motion, precipitable water, significant tornado parameter, storm relative helicity, and supercell composite. See the documentation for how to use each of these and their recpective sources.

Let's calculate an interesting parameter for this sounding from hurricane Irma - percipitable water:

In [ ]:
mpcalc.precipitable_water(data['dewpoint'], data['pressure'])
In [ ]:
mpcalc.precipitable_water(data['dewpoint'], data['pressure']).to('inches')
EXERCISE:
  • Calculate the bulk shear over the lowest 200 hPa of the sounding.

HINT: Look at the documentation for bulk_shear.

In [ ]:
# Your code goes here

shr_u, shr_v = mpcalc.bulk_shear(data['pressure'], data['u_wind'], data['v_wind'], depth=200 * units.hPa)
print(shr_u, shr_v)

Top


Adding fiducial lines and shading

Now that you’ve got the basics of the Skew-T down, it’s time to really dress it up. You could use the moist_lapse and dry_lapse functions in the calculations module to calculate and dry fiducials on the plot, but MetPy can do it for us.

In [ ]:
# Add the relevant special lines
skew.plot_dry_adiabats()

fig
EXERCISE:
  • Add moist adiabats to the skew-T using plot_moist_adiabats().
  • Add mixing ratio lines to the skew-T using plot_mixing_lines().
In [ ]:
# Your code goes here

skew.plot_moist_adiabats()
skew.plot_mixing_lines()

fig

We can also shade the areas that represent CAPE and CIN to make things a little more visually appealing.

In [ ]:
# Shade areas representing CAPE and CIN
skew.shade_cin(data['pressure'], data['temperature'], parcel_path)
skew.shade_cape(data['pressure'], data['temperature'], parcel_path)

fig

We can also highlight certain isotherms. One important isotherm is the freezing point of water. Let’s add a highlight to that line. The skew transform happens automatically!

In [ ]:
skew.ax.axvline(0, color='c', linestyle='--', linewidth=2)

fig

Top