2018-09-05 15:52:38 -06:00
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
2023-05-19 16:32:57 -06:00
"<a name=\"top\"></a>\n",
"<div style=\"width:1000 px\">\n",
2018-09-05 15:52:38 -06:00
"\n",
2023-05-19 16:32:57 -06:00
"<div style=\"float:right; width:98 px; height:98px;\">\n",
"<img src=\"https://docs.unidata.ucar.edu/images/logos/unidata_logo_vertical_150x150.png\" alt=\"Unidata Logo\" style=\"height: 98px;\">\n",
"</div>\n",
"\n",
"# Upper Air BUFR Soundings\n",
"**Python-AWIPS Tutorial Notebook**\n",
"\n",
"<div style=\"clear:both\"></div>\n",
"</div>\n",
"\n",
"---\n",
"\n",
"<div style=\"float:right; width:250 px\"><img src=\"../images/upper_air_bufr_sounding_preview.png\" alt=\"Preview image of the Skew-T plot generated by this notebook\" style=\"height: 300px;\"></div>\n",
"\n",
"\n",
"# Objectives\n",
"\n",
"* Retrieve an Upper Air vertical profile from EDEX\n",
"* Plot a Skew-T/Log-P chart with [Matplotlib](https://matplotlib.org/) and [MetPy](https://unidata.github.io/MetPy/latest/index.html)\n",
"* Understand the **bufrua** plugin returns separate objects for parameters at *mandatory levels* and at *significant temperature levels*\n",
" * *Significant temperature levels* are used to plot the pressure, temperature and dewpoint lines\n",
" * *Mandatory levels* are used to plot the wind profile\n",
"\n",
"\n",
"---"
]
},
{
"cell_type": "markdown",
"metadata": {
"toc": true
},
"source": [
"<h1>Table of Contents<span class=\"tocSkip\"></span></h1>\n",
2023-05-23 13:54:42 -06:00
"<div class=\"toc\"><ul class=\"toc-item\"><li><span><a href=\"#Imports\" data-toc-modified-id=\"Imports-1\"><span class=\"toc-item-num\">1 </span>Imports</a></span></li><li><span><a href=\"#EDEX-Connection\" data-toc-modified-id=\"EDEX-Connection-2\"><span class=\"toc-item-num\">2 </span>EDEX Connection</a></span><ul class=\"toc-item\"><li><span><a href=\"#Initial-EDEX-Connection\" data-toc-modified-id=\"Initial-EDEX-Connection-2.1\"><span class=\"toc-item-num\">2.1 </span>Initial EDEX Connection</a></span></li><li><span><a href=\"#Setting-Additional-Request-Parameters\" data-toc-modified-id=\"Setting-Additional-Request-Parameters-2.2\"><span class=\"toc-item-num\">2.2 </span>Setting Additional Request Parameters</a></span></li><li><span><a href=\"#Available-Location-Names\" data-toc-modified-id=\"Available-Location-Names-2.3\"><span class=\"toc-item-num\">2.3 </span>Available Location Names</a></span></li><li><span><a href=\"#Setting-the-Location-Name\" data-toc-modified-id=\"Setting-the-Location-Name-2.4\"><span class=\"toc-item-num\">2.4 </span>Setting the Location Name</a></span></li></ul></li><li><span><a href=\"#Filtering-by-Time\" data-toc-modified-id=\"Filtering-by-Time-3\"><span class=\"toc-item-num\">3 </span>Filtering by Time</a></span></li><li><span><a href=\"#Get-the-Data!\" data-toc-modified-id=\"Get-the-Data!-4\"><span class=\"toc-item-num\">4 </span>Get the Data!</a></span></li><li><span><a href=\"#Use-the-Data!\" data-toc-modified-id=\"Use-the-Data!-5\"><span class=\"toc-item-num\">5 </span>Use the Data!</a></span><ul class=\"toc-item\"><li><span><a href=\"#Prepare-Data-Objects\" data-toc-modified-id=\"Prepare-Data-Objects-5.1\"><span class=\"toc-item-num\">5.1 </span>Prepare Data Objects</a></span></li><li><span><a href=\"#Convert-Units\" data-toc-modified-id=\"Convert-Units-5.2\"><span class=\"toc-item-num\">5.2 </span>Convert Units</a></span></li></ul></li><li><span><a href=\"#Plot-the-Data!\" data-toc-modified-id=\"Plot-the-Data!-6\"><span class=\"toc-item-num\">6 </span>Plot the Data!</a></span></li><li><span><a href=\"#See-Also\" data-toc-modified-id=\"See-Also-7\"><span class=\"toc-item-num\">7 </span>See Also</a></span><ul class=\"toc-item\"><li><span><a href=\"#Related-Notebooks\" data-toc-modified-id=\"Related-Notebooks-7.1\"><span class=\"toc-item-num\">7.1 </span>Related Notebooks</a></span></li><li><span><a href=\"#Additional-Documentation\" data-toc-modified-id=\"Additional-Documentation-7.2\"><span class=\"toc-item-num\">7.2 </span>Additional Documentation</a></span></li></ul></li></ul></div>"
2023-05-19 16:32:57 -06:00
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Imports\n",
"\n",
"The imports below are used throughout the notebook. Note the first import is coming directly from python-awips and allows us to connect to an EDEX server. The subsequent imports are for data manipulation and visualization. "
2018-09-05 15:52:38 -06:00
]
},
{
"cell_type": "code",
2023-05-19 16:32:57 -06:00
"execution_count": 1,
2018-09-06 12:12:07 -06:00
"metadata": {},
2023-05-19 16:32:57 -06:00
"outputs": [],
2018-09-05 15:52:38 -06:00
"source": [
"from awips.dataaccess import DataAccessLayer\n",
"import matplotlib.pyplot as plt\n",
"from mpl_toolkits.axes_grid1.inset_locator import inset_axes\n",
"import numpy as np\n",
2023-05-19 16:32:57 -06:00
"from metpy.calc import wind_components, lcl, parcel_profile\n",
2018-09-05 15:52:38 -06:00
"from metpy.plots import SkewT, Hodograph\n",
2023-05-19 16:32:57 -06:00
"from metpy.units import units"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a href=\"#top\">Top</a>\n",
"\n",
"---"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## EDEX Connection\n",
"\n",
"### Initial EDEX Connection\n",
2018-09-05 15:52:38 -06:00
"\n",
2023-05-19 16:32:57 -06:00
"First we establish a connection to Unidata's public EDEX server. With that connection made, we can create a [new data request object](http://unidata.github.io/python-awips/api/IDataRequest.html) and set the data type to ***bufrua***, and define additional parameters and an identifier on the request."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"# Set the edex server\n",
2025-01-23 14:31:31 -07:00
"DataAccessLayer.changeEDEXHost(\"edex-beta.unidata.ucar.edu\")\n",
2018-09-05 15:52:38 -06:00
"request = DataAccessLayer.newDataRequest()\n",
"\n",
"# Set data type\n",
2023-05-19 16:32:57 -06:00
"request.setDatatype(\"bufrua\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Setting Additional Request Parameters\n",
"\n",
"Here we populate arrays of all the parameters that will be necessary for plotting the Skew-T. The `MAN_PARAMS` are the *mandatory levels* and the `SIGT_PARAMS` are the *significant temperature* parameters that were both mentioned in the [objectives section](#Objectives) above. \n",
"\n",
2023-05-25 11:54:03 -07:00
"Also request the station name and elevation to use in the figure title later on."
2023-05-19 16:32:57 -06:00
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
2023-05-25 11:54:03 -07:00
"MAN_PARAMS = set(['prMan', 'wdMan', 'wsMan'])\n",
2018-09-05 15:52:38 -06:00
"SIGT_PARAMS = set(['prSigT', 'tpSigT', 'tdSigT'])\n",
2023-05-19 16:32:57 -06:00
"request.setParameters(\"staElev\", \"staName\")\n",
2018-09-05 15:52:38 -06:00
"request.getParameters().extend(MAN_PARAMS)\n",
2023-05-19 16:32:57 -06:00
"request.getParameters().extend(SIGT_PARAMS)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Available Location Names\n",
"When working with a new data type, it is often useful to investigate all available options for a particular setting. Shown below is how to see all available location names for a data request with type **bufrua**. This step is not necessary if you already know exactly what the location ID you're interested in is."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<div class=\"alert-info\">\n",
"<b>Note:</b> It is important to note the location names are listed by their WMO Station ID. Their corresponding location and site identifier can be looked up in <a href=\"https://data.un.org/Data.aspx?d=CLINO&f=ElementCode%3a15%3bCountryCode%3aUS&c=2,5,6,7,10,15,18,19,20,22,24,26,28,30,32,34,36,38,40,42,44,46&s=CountryName:asc,WmoStationNumber:asc,StatisticCode:asc&v=1\"> this table from UNdata</a>.\n",
"</div>"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
2023-05-25 11:54:03 -07:00
"['21824', '21946', '24266', '24343', '24641', '24688', '24959', '25123', '25703', '25913', '31004', '31088', '31300', '31369', '31510', '31538', '31770', '31873', '32061', '32098', '32150', '32389', '32477', '32540', '32618', '47122', '47138', '47158', '47401', '47412', '47582', '47646', '47678', '47807', '47827', '47909', '47918', '47945', '47971', '47991', '70026', '70133', '70200', '70219', '70231', '70261', '70273', '70308', '70316', '70326', '70350', '70361', '70398', '70414', '71043', '71081', '71082', '71109', '71119', '71603', '71722', '71802', '71811', '71815', '71816', '71823', '71845', '71867', '71906', '71907', '71909', '71913', '71917', '71924', '71925', '71926', '71934', '71945', '71957', '71964', '72201', '72202', '72206', '72208', '72210', '72214', '72215', '72221', '72230', '72233', '72235', '72240', '72248', '72249', '72250', '72251', '72261', '72265', '72274', '72293', '72305', '72317', '72318', '72327', '72340', '72357', '72363', '72364', '72365', '72376', '72381', '72388', '72393', '72402', '72403', '72426', '72440', '72451', '72456', '72469', '72476', '72489', '72493', '72501', '72518', '72520', '72528', '72558', '72562', '72572', '72582', '72597', '72632', '72634', '72645', '72649', '72659', '72662', '72672', '72681', '72694', '72712', '72747', '72764', '72768', '72776', '72786', '72797', '74004', '74005', '74389', '74455', '74560', '74794', '78016', '78384', '78397', '78486', '78526', '78583', '78866', '78954', '78970', '78988', '80001', '91165', '91212', '91285', '91334', '91348', '91366', '91376', '91408', '91413', '91610', '91643', '91680', '91765', '94120', '94203', '94299', '94332', '94461', '94510', '94578', '94637', '94638', '94653', '94659', '94672', '94711', '94776', '94996']\n"
2023-05-19 16:32:57 -06:00
]
}
],
"source": [
2018-09-06 12:12:07 -06:00
"locations = DataAccessLayer.getAvailableLocationNames(request)\n",
"locations.sort()\n",
2023-05-19 16:32:57 -06:00
"print(locations)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Setting the Location Name\n",
2018-09-05 15:52:38 -06:00
"\n",
2023-05-19 16:32:57 -06:00
"In this case we're setting the location name to the ID for `KLBF` which is the North Platte Regional Airport/Lee Bird, Field in Nebraska."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
2018-09-05 15:52:38 -06:00
"# Set station ID (not name)\n",
2023-05-19 16:32:57 -06:00
"request.setLocationNames(\"72562\") #KLBF"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a href=\"#top\">Top</a>\n",
2018-09-05 15:52:38 -06:00
"\n",
2023-05-19 16:32:57 -06:00
"---"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Filtering by Time\n",
"\n",
"Models produce many different time variants during their runs, so let's limit the data to the most recent time and forecast run."
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
2018-09-05 15:52:38 -06:00
"# Get all times\n",
2023-05-19 16:32:57 -06:00
"datatimes = DataAccessLayer.getAvailableTimes(request)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a href=\"#top\">Top</a>\n",
"\n",
"---"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Get the Data!\n",
"\n",
"Here we can now request our data response from the EDEX server with our defined time filter.\n",
2018-09-05 15:52:38 -06:00
"\n",
2023-05-19 16:32:57 -06:00
"Printing out some data from the first object in the response array can help verify we received the data we were interested in."
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
2023-05-25 11:54:03 -07:00
"parms = ['tpSigT', 'prSigT', 'tdSigT']\n",
2023-05-19 16:32:57 -06:00
"site = 72562\n",
"geom = POINT (-100.7005615234375 41.14971923828125)\n",
2023-05-25 11:54:03 -07:00
"datetime = 2023-05-25 12:00:00\n",
"reftime = May 25 23 12:00:00 GMT\n",
2023-05-19 16:32:57 -06:00
"fcstHour = 0\n",
2023-05-25 11:54:03 -07:00
"period = (May 25 23 12:00:00 , May 25 23 12:00:00 )\n"
2023-05-19 16:32:57 -06:00
]
}
],
"source": [
2018-09-05 15:52:38 -06:00
"# Get most recent record\n",
"response = DataAccessLayer.getGeometryData(request,times=datatimes[-1].validPeriod)\n",
2023-05-19 16:32:57 -06:00
"obj = response[0]\n",
2018-09-05 15:52:38 -06:00
"\n",
2023-05-19 16:32:57 -06:00
"print(\"parms = \" + str(obj.getParameters()))\n",
"print(\"site = \" + str(obj.getLocationName()))\n",
"print(\"geom = \" + str(obj.getGeometry()))\n",
"print(\"datetime = \" + str(obj.getDataTime()))\n",
"print(\"reftime = \" + str(obj.getDataTime().getRefTime()))\n",
"print(\"fcstHour = \" + str(obj.getDataTime().getFcstTime()))\n",
"print(\"period = \" + str(obj.getDataTime().getValidPeriod()))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a href=\"#top\">Top</a>\n",
"\n",
"---"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Use the Data!\n",
"\n",
"Since we filtered on time, and requested the data in the previous cell, we now have a `response` object we can work with.\n",
"\n",
2023-05-23 13:54:42 -06:00
"### Prepare Data Objects\n",
2023-05-19 16:32:57 -06:00
"\n",
2023-05-25 11:54:03 -07:00
"Here we construct arrays for each parameter to plot (temperature, dewpoint, pressure, and wind components).\n",
2023-05-19 16:32:57 -06:00
"After populating each of the arrays, we sort and mask missing data."
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
2018-09-05 15:52:38 -06:00
"# Initialize data arrays\n",
2023-05-25 11:54:03 -07:00
"prMan,wdMan,wsMan = np.array([]),np.array([]),np.array([])\n",
2018-09-05 15:52:38 -06:00
"prSig,tpSig,tdSig = np.array([]),np.array([]),np.array([])\n",
"manGeos = []\n",
"sigtGeos = []\n",
"\n",
"# Build arrays\n",
"for ob in response:\n",
2018-10-09 13:39:16 -06:00
" parm_array = ob.getParameters()\n",
2018-09-06 12:12:07 -06:00
" if set(parm_array) & MAN_PARAMS:\n",
2018-09-05 15:52:38 -06:00
" manGeos.append(ob)\n",
2018-10-05 17:09:43 -06:00
" prMan = np.append(prMan,ob.getNumber(\"prMan\"))\n",
" wdMan = np.append(wdMan,ob.getNumber(\"wdMan\"))\n",
2018-10-15 16:29:13 -06:00
" wsMan, wsUnit = np.append(wsMan,ob.getNumber(\"wsMan\")), ob.getUnit(\"wsMan\")\n",
2018-09-05 15:52:38 -06:00
" continue\n",
2018-09-06 12:12:07 -06:00
" if set(parm_array) & SIGT_PARAMS:\n",
2018-09-05 15:52:38 -06:00
" sigtGeos.append(ob)\n",
2018-10-05 17:09:43 -06:00
" prSig = np.append(prSig,ob.getNumber(\"prSigT\"))\n",
" tpSig = np.append(tpSig,ob.getNumber(\"tpSigT\"))\n",
2023-05-25 11:54:03 -07:00
" tpUnit = ob.getUnit(\"tpSigT\")\n",
2018-10-05 17:09:43 -06:00
" tdSig = np.append(tdSig,ob.getNumber(\"tdSigT\"))\n",
2018-09-05 15:52:38 -06:00
" continue\n",
"\n",
"# Sort mandatory levels (but not sigT levels) because of the 1000.MB interpolation inclusion\n",
"ps = prMan.argsort()[::-1]\n",
"wpres = prMan[ps]\n",
"direc = wdMan[ps]\n",
"spd = wsMan[ps]\n",
"\n",
"# Flag missing data\n",
"prSig[prSig <= -9999] = np.nan\n",
"tpSig[tpSig <= -9999] = np.nan\n",
"tdSig[tdSig <= -9999] = np.nan\n",
"wpres[wpres <= -9999] = np.nan\n",
"direc[direc <= -9999] = np.nan\n",
2023-05-19 16:32:57 -06:00
"spd[spd <= -9999] = np.nan"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Convert Units\n",
2018-09-05 15:52:38 -06:00
"\n",
2023-05-30 12:25:21 -06:00
"We need to modify the units several of the data parameters are returned in. Here we convert the units for Temperature and Dewpoint from Kelvin to Celsius, convert pressure to milibars, and extract wind for both the u and v directional components in Knots and Radians. "
2023-05-19 16:32:57 -06:00
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
2018-09-05 15:52:38 -06:00
"# assign units\n",
"p = (prSig/100) * units.mbar\n",
"wpres = (wpres/100) * units.mbar\n",
2020-09-03 13:28:04 -06:00
"u,v = wind_components(spd * units.knots, np.deg2rad(direc))\n",
2018-09-05 15:52:38 -06:00
"\n",
2020-09-03 13:34:50 -06:00
"if tpUnit == 'K':\n",
2018-10-15 16:29:13 -06:00
" T = (tpSig-273.15) * units.degC\n",
2023-05-25 11:54:03 -07:00
" Td = (tdSig-273.15) * units.degC"
2023-05-19 16:32:57 -06:00
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a href=\"#top\">Top</a>\n",
"\n",
"---"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Plot the Data!\n",
2018-10-15 16:29:13 -06:00
"\n",
2023-05-19 16:32:57 -06:00
"Create and display SkewT and Hodograph plots using MetPy."
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
2023-05-25 11:54:03 -07:00
"image/png": "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
2023-05-19 16:32:57 -06:00
"text/plain": [
"<Figure size 720x864 with 2 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
2018-09-05 15:52:38 -06:00
"# Create SkewT/LogP\n",
2018-10-09 13:39:16 -06:00
"plt.rcParams['figure.figsize'] = (10, 12)\n",
2018-09-05 15:52:38 -06:00
"skew = SkewT()\n",
"skew.plot(p, T, 'r', linewidth=2)\n",
"skew.plot(p, Td, 'g', linewidth=2)\n",
"skew.plot_barbs(wpres, u, v)\n",
"skew.ax.set_ylim(1000, 100)\n",
2018-09-06 12:12:07 -06:00
"skew.ax.set_xlim(-60, 30)\n",
2018-09-05 15:52:38 -06:00
"\n",
"title_string = \" T(F) Td \" \n",
2018-10-05 17:09:43 -06:00
"title_string += \" \" + str(ob.getString(\"staName\"))\n",
2018-09-05 15:52:38 -06:00
"title_string += \" \" + str(ob.getDataTime().getRefTime())\n",
2018-10-05 17:09:43 -06:00
"title_string += \" (\" + str(ob.getNumber(\"staElev\")) + \"m elev)\"\n",
2018-09-05 15:52:38 -06:00
"title_string += \"\\n\" + str(round(T[0].to('degF').item(),1))\n",
"title_string += \" \" + str(round(Td[0].to('degF').item(),1))\n",
"plt.title(title_string, loc='left')\n",
"\n",
"# Calculate LCL height and plot as black dot\n",
2018-09-06 12:12:07 -06:00
"lcl_pressure, lcl_temperature = lcl(p[0], T[0], Td[0])\n",
"skew.plot(lcl_pressure, lcl_temperature, 'ko', markerfacecolor='black')\n",
2018-09-05 15:52:38 -06:00
"\n",
"# Calculate full parcel profile and add to plot as black line\n",
"prof = parcel_profile(p, T[0], Td[0]).to('degC')\n",
"skew.plot(p, prof, 'k', linewidth=2)\n",
"\n",
"# An example of a slanted line at constant T -- in this case the 0 isotherm\n",
"l = skew.ax.axvline(0, color='c', linestyle='--', linewidth=2)\n",
"\n",
"# Draw hodograph\n",
"ax_hod = inset_axes(skew.ax, '30%', '30%', loc=3)\n",
"h = Hodograph(ax_hod, component_range=max(wsMan))\n",
"h.add_grid(increment=20)\n",
"h.plot_colormapped(u, v, spd)\n",
"\n",
"# Show the plot\n",
"plt.show()"
]
2023-05-19 16:32:57 -06:00
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a href=\"#top\">Top</a>\n",
"\n",
"---"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## See Also\n",
"\n",
"### Related Notebooks\n",
"\n",
"* [Grid Levels and Parameters](https://unidata.github.io/python-awips/examples/generated/Grid_Levels_and_Parameters.html)\n",
"* [Model Sounding Data](http://unidata.github.io/python-awips/examples/generated/Model_Sounding_Data.html)\n",
"* [Forecast Model Vertical Sounding](http://unidata.github.io/python-awips/examples/generated/Forecast_Model_Vertical_Sounding.html)\n",
"\n",
"### Additional Documentation\n",
"\n",
"**python-awips:**\n",
"\n",
"* [awips.DataAccessLayer](http://unidata.github.io/python-awips/api/DataAccessLayer.html)\n",
"* [awips.PyGeometryData](http://unidata.github.io/python-awips/api/PyGeometryData.html)\n",
"\n",
"**matplotlib:**\n",
"\n",
"* [matplotlib.pyplot](https://matplotlib.org/3.3.3/api/_as_gen/matplotlib.pyplot.html)\n",
"\n",
"**MetPy**\n",
"\n",
"* [metpy.wind_components](https://unidata.github.io/MetPy/latest/api/generated/metpy.calc.wind_components.html)\n",
"* [metpy.lcl](https://unidata.github.io/MetPy/latest/api/generated/metpy.calc.lcl.html) (Lifted Condensation Level)\n",
"* [metpy.parcel_profile](https://unidata.github.io/MetPy/latest/api/generated/metpy.calc.parcel_profile.html)\n",
"* [metpy.skewt](https://unidata.github.io/MetPy/latest/api/generated/metpy.plots.SkewT.html)\n",
"* [metpy.hodograph](https://unidata.github.io/MetPy/latest/api/generated/metpy.plots.Hodograph.html)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a href=\"#top\">Top</a>\n",
"\n",
"---"
]
2018-09-05 15:52:38 -06:00
}
],
"metadata": {
"kernelspec": {
2023-08-24 12:49:20 -06:00
"display_name": "Python 3 (ipykernel)",
2018-09-05 15:52:38 -06:00
"language": "python",
2018-09-06 12:12:07 -06:00
"name": "python3"
2018-09-05 15:52:38 -06:00
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
2018-09-06 12:12:07 -06:00
"version": 3
2018-09-05 15:52:38 -06:00
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
2018-09-06 12:12:07 -06:00
"pygments_lexer": "ipython3",
2025-01-23 14:31:31 -07:00
"version": "3.11.11"
2023-05-19 16:32:57 -06:00
},
"toc": {
"base_numbering": 1,
"nav_menu": {},
"number_sections": true,
"sideBar": true,
"skip_h1_title": true,
"title_cell": "Table of Contents",
"title_sidebar": "Contents",
"toc_cell": true,
"toc_position": {},
"toc_section_display": true,
"toc_window_display": true
2018-09-05 15:52:38 -06:00
}
},
"nbformat": 4,
2025-01-23 14:31:31 -07:00
"nbformat_minor": 4
2018-09-05 15:52:38 -06:00
}