Skew-T Analysis
Create a Skew-T plot using remote data from University of Wyoming.
This example uses example data from the University of Wyoming sounding archive for 12 UTC 31 October 2016 for Minneapolis, MN (MPX).
Imports
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import metpy.calc as mpcalc
from metpy.cbook import get_test_data
from metpy.plots import add_metpy_logo, SkewT
from metpy.units import units
from datetime import datetime
from siphon.simplewebservice.wyoming import WyomingUpperAir
Obtain Data and Format
This requires an internet connection to access the sounding data from a
remote server at the University of Wyoming.
First we will create variables for date, time and station.
Format: datetime(YYYY, MM, DD, HH)
The station
entry will need the be the three letter identifier of the station you want to look at. The National Center for Atmospheric Research (NCAR) Research Applications Labratory (RAL) continously updates a detailed list of all stations.
# Create variables for preferred date, time and station
preferred_date = datetime(2016, 10, 26, 12)
station = 'MPX'
# Read remote sounding data based on preferred_date and station
sounding_data = WyomingUpperAir.request_data(preferred_date, station)
---------------------------------------------------------------------------
HTTPError Traceback (most recent call last)
Cell In[3], line 2
1 # Read remote sounding data based on preferred_date and station
----> 2 sounding_data = WyomingUpperAir.request_data(preferred_date, station)
File ~/miniconda3/envs/cookbook-dev/lib/python3.10/site-packages/siphon/simplewebservice/wyoming.py:50, in WyomingUpperAir.request_data(cls, time, site_id, **kwargs)
30 r"""Retrieve upper air observations from the Wyoming archive.
31
32 Parameters
(...)
47
48 """
49 endpoint = cls()
---> 50 df = endpoint._get_data(time, site_id)
51 return df
File ~/miniconda3/envs/cookbook-dev/lib/python3.10/site-packages/siphon/simplewebservice/wyoming.py:70, in WyomingUpperAir._get_data(self, time, site_id)
53 def _get_data(self, time, site_id):
54 r"""Download and parse upper air observations from an online archive.
55
56 Parameters
(...)
68
69 """
---> 70 raw_data = self._get_data_raw(time, site_id)
71 soup = BeautifulSoup(raw_data, 'html.parser')
72 tabular_data = StringIO(soup.find_all('pre')[0].contents[0])
File ~/miniconda3/envs/cookbook-dev/lib/python3.10/site-packages/siphon/simplewebservice/wyoming.py:144, in WyomingUpperAir._get_data_raw(self, time, site_id)
126 """Download data from the University of Wyoming's upper air archive.
127
128 Parameters
(...)
138
139 """
140 path = ('?region=naconf&TYPE=TEXT%3ALIST'
141 '&YEAR={time:%Y}&MONTH={time:%m}&FROM={time:%d%H}&TO={time:%d%H}'
142 '&STNM={stid}').format(time=time, stid=site_id)
--> 144 resp = self.get_path(path)
145 # See if the return is valid, but has no data
146 if resp.text.find("Can't") != -1:
File ~/miniconda3/envs/cookbook-dev/lib/python3.10/site-packages/siphon/http_util.py:457, in HTTPEndPoint.get_path(self, path, query)
434 def get_path(self, path, query=None):
435 """Make a GET request, optionally including a query, to a relative path.
436
437 The path of the request includes a path on top of the base URL
(...)
455
456 """
--> 457 return self.get(self.url_path(path), query)
File ~/miniconda3/envs/cookbook-dev/lib/python3.10/site-packages/siphon/http_util.py:492, in HTTPEndPoint.get(self, path, params)
490 else:
491 text = resp.text
--> 492 raise requests.HTTPError('Error accessing {0}\n'
493 'Server Error ({1:d}: {2})'.format(resp.request.url,
494 resp.status_code,
495 text))
496 return resp
HTTPError: Error accessing http://weather.uwyo.edu/cgi-bin/sounding/?region=naconf&TYPE=TEXT%3ALIST&YEAR=2016&MONTH=10&FROM=2612&TO=2612&STNM=MPX
Server Error (503: Sorry, the server is too busy to process your request.
Please try again later.
)
sounding_data
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[4], line 1
----> 1 sounding_data
NameError: name 'sounding_data' is not defined
Assign Units
We will pull the data out of the example dataset into individual variables and assign units. This is explained in further detain in the Simple Sounding notebook and in the Metpy documentation.
pres = sounding_data['pressure'].values * units.hPa
temp = sounding_data['temperature'].values * units.degC
dewpoint = sounding_data['dewpoint'].values * units.degC
wind_speed = sounding_data['speed'].values * units.knots
wind_dir = sounding_data['direction'].values * units.degrees
u = sounding_data['u_wind'].values * units.knots
v = sounding_data['v_wind'].values * units.knots
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[5], line 1
----> 1 pres = sounding_data['pressure'].values * units.hPa
2 temp = sounding_data['temperature'].values * units.degC
3 dewpoint = sounding_data['dewpoint'].values * units.degC
NameError: name 'sounding_data' is not defined
Create Sounding Plot
# Create figure and set size
fig = plt.figure(figsize=(9, 9))
skew = SkewT(fig, rotation=45)
# Plot temperature and dewpoint lines
skew.plot(pres, temp, 'red')
skew.plot(pres, dewpoint, 'green')
# Plot wind barbs
my_interval = np.arange(100, 1000, 25) * units('hPa')
ix = mpcalc.resample_nn_1d(pres, my_interval)
skew.plot_barbs(pres[ix], u[ix], v[ix], y_clip_radius=0.001)
# Improve labels and set axis limits
skew.ax.set_xlabel('Temperature (\N{DEGREE CELSIUS})')
skew.ax.set_ylabel('Pressure (hPa)')
skew.ax.set_ylim(1000, 100)
# Add the relevant special lines
skew.plot_dry_adiabats(t0=np.arange(233, 533, 10) * units.K, alpha=0.25, color='orangered')
skew.plot_moist_adiabats(t0=np.arange(233, 400, 5) * units.K, alpha=0.25, color='tab:green')
skew.plot_mixing_lines(pressure=np.arange(1000, 99, -25) * units.hPa, linestyle='dotted', color='tab:blue')
# Add the MetPy logo!
fig = plt.gcf()
add_metpy_logo(fig, 115, 100, size='small');
# Add some descriptive titles
plt.title('{} Sounding'.format(station), loc='left')
plt.title('Valid Time: {}'.format(preferred_date), loc='right');
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[6], line 6
3 skew = SkewT(fig, rotation=45)
5 # Plot temperature and dewpoint lines
----> 6 skew.plot(pres, temp, 'red')
7 skew.plot(pres, dewpoint, 'green')
9 # Plot wind barbs
NameError: name 'pres' is not defined