<jupyter_start><jupyter_text>Upper Air and the Skew-T Log-PUnidata Python Workshop Overview:* **Teaching:** 30 minutes* **Exercises:** 60 minutes Questions1. Where can upper air data be found and what format is it in?1. How can I obtain upper air data programatically?1. How can MetPy be used to make a Skew-T Log-P diagram?1. What calculations can be performed on the data? Objectives1. Obtain upper air data1. Make a simple plot1. Make a Skew-T1. Calculate LCL, LFC, EL1. Parcel Path1. Calculate CAPE and CIN1. Other parameters1. Adding fiducial lines and shading1. Plotting a hodograph  Obtain upper air dataUpper 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](http://weather.uwyo.edu/upperair/sounding.html), the [Iowa State archive](https://mesonet.agron.iastate.edu/archive/raob/), and the [Integrated Global Radiosonde Archive (IGRA)](https://www.ncdc.noaa.gov/data-access/weather-balloon/integrated-global-radiosonde-archive). **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.<jupyter_code>from datetime import datetime

from siphon.simplewebservice.wyoming import WyomingUpperAir

date = datetime(2017, 9, 10, 6)
station = 'MFL'
df = WyomingUpperAir.request_data(date, station)<jupyter_output><empty_output><jupyter_text>The data are returned as a `pandas` `DataFrame`:<jupyter_code>df<jupyter_output><empty_output><jupyter_text>Next, we will pull out the data and attach the units which are stored in a dictionary in the `DataFrame` attribute `units`.<jupyter_code>from metpy.units import pandas_dataframe_to_unit_arrays, units

data = pandas_dataframe_to_unit_arrays(df)<jupyter_output><empty_output><jupyter_text>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.<jupyter_code># Your code goes here<jupyter_output><empty_output><jupyter_text>View Solutiondf = WyomingUpperAir.request_data(datetime(2017, 9, 10, 0), 'KEY')data = pandas_dataframe_to_unit_arrays(df) Top  Make a Simple PlotKnowing 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!<jupyter_code>import matplotlib.pyplot as plt
%matplotlib inline
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)<jupyter_output><empty_output><jupyter_text>Top  Make a Skew-TAs 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!<jupyter_code>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')<jupyter_output><empty_output><jupyter_text>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.<jupyter_code># 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<jupyter_output><empty_output><jupyter_text>EXERCISE:           Add a blue line for dewpoint.      Set the x-axis limits to something sensible.<jupyter_code># Your code goes here<jupyter_output><empty_output><jupyter_text>View Solutionskew.plot(data['pressure'], data['dewpoint'], color='blue')skew.ax.set_xlim(-40, 60)fig Top  Calculate LCL, LFC, ELGenerally 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.<jupyter_code>import metpy.calc as mpcalc

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

fig<jupyter_output><empty_output><jupyter_text>EXERCISE:           Add the LFC to the plot (lfc takes the pressure, temperature, and dewpoint profiles).      Add the EL to the plot.<jupyter_code># Your code goes here<jupyter_output><empty_output><jupyter_text>View Solution Calculate the LFC and plot it if it existslfc_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 existsel_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 PathWhen 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).<jupyter_code>parcel_path = mpcalc.parcel_profile(data['pressure'],
                                    data['temperature'][0],
                                    data['dewpoint'][0]).to('degC')
print(parcel_path)
skew.plot(data['pressure'], parcel_path, color='black')
fig<jupyter_output><empty_output><jupyter_text>Top  Calculate CAPE and CINSome 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!<jupyter_code>mpcalc.surface_based_cape_cin(data['pressure'], data['temperature'], data['dewpoint'])<jupyter_output><empty_output><jupyter_text>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.<jupyter_code># Your code goes here<jupyter_output><empty_output><jupyter_text>View Solutionmpcalc.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 ParametersThere 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:<jupyter_code>mpcalc.precipitable_water(data['dewpoint'], data['pressure'])
mpcalc.precipitable_water(data['dewpoint'], data['pressure']).to('inches')<jupyter_output><empty_output><jupyter_text>EXERCISE:           Calculate the bulk shear over the lowest 200 hPa of the sounding.            HINT: Look at the documentation for bulk_shear.<jupyter_code># Your code goes here<jupyter_output><empty_output><jupyter_text>View Solutionshr_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 shadingNow 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.<jupyter_code># Add the relevant special lines
skew.plot_dry_adiabats()

fig<jupyter_output><empty_output><jupyter_text>EXERCISE:          Add moist adiabats to the skew-T using plot_moist_adiabats().      Add mixing ratio lines to the skew-T using plot_mixing_lines().<jupyter_code># Your code goes here<jupyter_output><empty_output><jupyter_text>View Solutionskew.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.<jupyter_code># 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<jupyter_output><empty_output><jupyter_text>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!<jupyter_code>skew.ax.axvline(0, color='c', linestyle='--', linewidth=2)

fig<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.0958208684616082, 'fraction_numerical': 0.020759677273139335, 'mean_word_length': 4.12639405204461, 'pattern_counts': {'":': 0, '<': 77, '<?xml version=': 0, '>': 77, 'https://': 2, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 13, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '19', 'dir': 'jupyter-structured-clean-dedup', 'id': '177848', 'license': 'MIT', 'n_tokens_mistral': 3476, 'n_tokens_neox': 3170, 'n_words': 1212, 'path': 'notebooks/Skew_T/Upper Air and the Skew-T Log-P.ipynb', 'repo_name': 'helsing97/Unidata-Workshop', 'size': '11031'}