2018-10-11 11:59:44 -06:00
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
2022-11-11 13:02:19 -07:00
"<a name=\"top\"></a>\n",
"<div style=\"width:1000 px\">\n",
"\n",
"<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",
"# Regional Surface Obs Plot\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/regional_obs_preview.png\" alt=\"Sample image of Regional surface observations\" style=\"height: 300px;\"></div>\n",
"\n",
"\n",
"# Objectives\n",
"\n",
"* Use python-awips to connect to an edex server\n",
"* Create a plot for a regional area of the United States (Florida)\n",
"* Define and filter data request for METAR and Synoptic surface obs\n",
"* Use the maps database to request and draw state boundaries (no use of Cartopy.Feature in this example)\n",
"* Stylize and plot surface data using Metpy\n",
"\n",
"---"
]
},
{
"cell_type": "markdown",
"metadata": {
"toc": true
},
"source": [
"<h1>Table of Contents<span class=\"tocSkip\"></span></h1>\n",
2022-11-15 10:06:17 -07: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=\"#Function:-get_cloud_cover()\" data-toc-modified-id=\"Function:-get_cloud_cover()-2\"><span class=\"toc-item-num\">2 </span>Function: get_cloud_cover()</a></span></li><li><span><a href=\"#Function:-make_map()\" data-toc-modified-id=\"Function:-make_map()-3\"><span class=\"toc-item-num\">3 </span>Function: make_map()</a></span></li><li><span><a href=\"#Function:-extract_plotting_data()\" data-toc-modified-id=\"Function:-extract_plotting_data()-4\"><span class=\"toc-item-num\">4 </span>Function: extract_plotting_data()</a></span></li><li><span><a href=\"#Function:-plot_data()\" data-toc-modified-id=\"Function:-plot_data()-5\"><span class=\"toc-item-num\">5 </span>Function: plot_data()</a></span></li><li><span><a href=\"#Initial-Setup\" data-toc-modified-id=\"Initial-Setup-6\"><span class=\"toc-item-num\">6 </span>Initial Setup</a></span><ul class=\"toc-item\"><li><span><a href=\"#Initial-EDEX-Connection\" data-toc-modified-id=\"Initial-EDEX-Connection-6.1\"><span class=\"toc-item-num\">6.1 </span>Initial EDEX Connection</a></span></li><li><span><a href=\"#Maps-Request-and-Response\" data-toc-modified-id=\"Maps-Request-and-Response-6.2\"><span class=\"toc-item-num\">6.2 </span>Maps Request and Response</a></span></li><li><span><a href=\"#Define-Geographic-Filter\" data-toc-modified-id=\"Define-Geographic-Filter-6.3\"><span class=\"toc-item-num\">6.3 </span>Define Geographic Filter</a></span></li><li><span><a href=\"#Define-Time-Filter\" data-toc-modified-id=\"Define-Time-Filter-6.4\"><span class=\"toc-item-num\">6.4 </span>Define Time Filter</a></span></li><li><span><a href=\"#Define-Common-Parameters-for-Data-Requests\" data-toc-modified-id=\"Define-Common-Parameters-for-Data-Requests-6.5\"><span class=\"toc-item-num\">6.5 </span>Define Common Parameters for Data Requests</a></span></li><li><span><a href=\"#Define-METAR-Request\" data-toc-modified-id=\"Define-METAR-Request-6.6\"><span class=\"toc-item-num\">6.6 </span>Define METAR Request</a></span></li><li><span><a href=\"#Define-Synoptic-Request\" data-toc-modified-id=\"Define-Synoptic-Request-6.7\"><span class=\"toc-item-num\">6.7 </span>Define Synoptic Request</a></span></li></ul></li><li><span><a href=\"#Get-the-Data!\" data-toc-modified-id=\"Get-the-Data!-7\"><span class=\"toc-item-num\">7 </span>Get the Data!</a></span><ul class=\"toc-item\"><li><span><a href=\"#Get-the-EDEX-Responses\" data-toc-modified-id=\"Get-the-EDEX-Responses-7.1\"><span class=\"toc-item-num\">7.1 </span>Get the EDEX Responses</a></span></li><li><span><a href=\"#Extract-Plotting-Data\" data-toc-modified-id=\"Extract-Plotting-Data-7.2\"><span class=\"toc-item-num\">7.2 </span>Extract Plotting Data</a></span></li></ul></li><li><span><a href=\"#Plot-the-Data\" data-toc-modified-id=\"Plot-the-Data-8\"><span class=\"toc-item-num\">8 </span>Plot the Data</a></span><ul class=\"toc-item\"><li><span><a href=\"#Draw-the-Region\" data-toc-modified-id=\"Draw-the-Region-8.1\"><span class=\"toc-item-num\">8.1 </span>Draw the Region</a></span></li><li><span><a href=\"#Plot-METAR-Data\" data-toc-modified-id=\"Plot-METAR-Data-8.2\"><span class=\"toc-item-num\">8.2 </span>Plot METAR Data</a></span></li><li><span><a href=\"#Plot-Synoptic-Data\" data-toc-modified-id=\"Plot-Synoptic-Data-8.3\"><span class=\"toc-item-num\">8.3 </span>Plot Synoptic Data</a></span></li><li><span><a href=\"#Plot-both-METAR-and-Synoptic-Data\" data-toc-modified-id=\"Plot-both-METAR-and-Synoptic-Data-8.4\"><span class=\"toc-item-num\">8.4 </span>Plot both METAR and Synoptic Data</a></span></li></ul></li><li><span><a href=\"#See-Also\" data-toc-modified-id=\"See-Also-9\"><span class=\"toc-item-num\">9 </span>
2022-11-11 13:02:19 -07:00
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Imports\n",
"\n",
"The imports below are used throughout the notebook. Note the first two imports are coming directly from python-awips and allow us to connect to an EDEX server, and define a timrange used for filtering the data. The subsequent imports are for data manipulation and visualization. "
2018-10-11 11:59:44 -06:00
]
},
{
"cell_type": "code",
2025-02-12 17:02:03 -07:00
"execution_count": 1,
2018-10-11 11:59:44 -06:00
"metadata": {},
"outputs": [],
"source": [
"from awips.dataaccess import DataAccessLayer\n",
"from dynamicserialize.dstypes.com.raytheon.uf.common.time import TimeRange\n",
2025-01-23 14:31:31 -07:00
"from datetime import datetime, timedelta, UTC\n",
2018-10-11 11:59:44 -06:00
"import numpy as np\n",
"import cartopy.crs as ccrs\n",
"from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER\n",
"from cartopy.feature import ShapelyFeature\n",
2018-10-11 13:36:14 -06:00
"from shapely.geometry import Polygon\n",
2018-10-11 11:59:44 -06:00
"import matplotlib.pyplot as plt\n",
"from metpy.units import units\n",
"from metpy.calc import wind_components\n",
2022-11-11 13:02:19 -07:00
"from metpy.plots import simple_layout, StationPlot, StationPlotLayout, sky_cover\n",
"import warnings"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a href=\"#top\">Top</a>\n",
"\n",
"---"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Function: get_cloud_cover()\n",
2018-10-11 11:59:44 -06:00
"\n",
2022-11-11 13:02:19 -07:00
"Returns the cloud coverage values as integer codes (0 through 8)."
]
},
{
"cell_type": "code",
2025-02-12 17:02:03 -07:00
"execution_count": 2,
2022-11-11 13:02:19 -07:00
"metadata": {},
"outputs": [],
"source": [
2018-10-11 11:59:44 -06:00
"def get_cloud_cover(code):\n",
" if 'OVC' in code:\n",
2022-11-11 13:02:19 -07:00
" return 8\n",
2018-10-11 11:59:44 -06:00
" elif 'BKN' in code:\n",
2022-11-11 13:02:19 -07:00
" return 6\n",
2018-10-11 11:59:44 -06:00
" elif 'SCT' in code:\n",
2022-11-11 13:02:19 -07:00
" return 4\n",
2018-10-11 11:59:44 -06:00
" elif 'FEW' in code:\n",
2022-11-11 13:02:19 -07:00
" return 2\n",
2018-10-11 11:59:44 -06:00
" else:\n",
" return 0"
]
},
2022-11-11 13:02:19 -07:00
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a href=\"#top\">Top</a>\n",
"\n",
"---"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Function: make_map()\n",
"\n",
"In order to plot more than one image, it's easiest to define common logic in a function. Here, a new function called **make_map** is defined. This function uses the [matplotlib.pyplot package (plt)](https://matplotlib.org/3.3.3/api/_as_gen/matplotlib.pyplot.html) to create a figure and axis. The geographic extent is set and lat/lon gridlines are added for context."
]
},
2018-10-11 11:59:44 -06:00
{
"cell_type": "code",
2025-02-12 17:02:03 -07:00
"execution_count": 3,
2018-10-11 11:59:44 -06:00
"metadata": {},
2022-11-11 13:02:19 -07:00
"outputs": [],
"source": [
"def make_map(bbox, proj=ccrs.PlateCarree()):\n",
" fig, ax = plt.subplots(figsize=(16,12),subplot_kw=dict(projection=proj))\n",
" ax.set_extent(bbox)\n",
" gl = ax.gridlines(draw_labels=True, color='#e7e7e7')\n",
" gl.top_labels = gl.right_labels = False\n",
" gl.xformatter = LONGITUDE_FORMATTER\n",
" gl.yformatter = LATITUDE_FORMATTER\n",
" return fig, ax"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a href=\"#top\">Top</a>\n",
"\n",
"---"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Function: extract_plotting_data()\n",
"\n",
"Grab the simple variables out of the response data we have (attaching correct units), and\n",
"put them into a dictionary that we will hand the plotting function later:\n",
"\n",
"- Get wind components from speed and direction\n",
"- Convert cloud coverage values to integer codes [0 - 8]\n",
"- Assign temperature, dewpoint, and sea level pressure the the correct units\n",
"- Account for missing values (by using `nan`)"
]
},
{
"cell_type": "code",
2025-02-12 17:02:03 -07:00
"execution_count": 4,
2022-11-11 13:02:19 -07:00
"metadata": {},
"outputs": [],
"source": [
"def extract_plotting_data(arr, datatype):\n",
" \"\"\"\n",
" Extract all necessary data for plotting for either\n",
" datatype: 'obs' or 'sfcobs'\n",
" \"\"\"\n",
" \n",
" data = dict()\n",
" data['latitude'] = np.array(arr['latitude'])\n",
" data['longitude'] = np.array(arr['longitude'])\n",
" tmp = np.array(arr['temperature'], dtype=float)\n",
" dpt = np.array(arr['dewpoint'], dtype=float)\n",
" direction = np.array(arr['windDir'])\n",
"\n",
" # Suppress nan masking warnings\n",
" warnings.filterwarnings(\"ignore\",category =RuntimeWarning)\n",
" \n",
" # Account for missing values\n",
" tmp[tmp == -9999.0] = 'nan'\n",
" dpt[dpt == -9999.] = 'nan'\n",
" direction[direction == -9999.0] = 'nan'\n",
" \n",
" data['air_pressure_at_sea_level'] = np.array(arr['seaLevelPress'])* units('mbar')\n",
" u, v = wind_components(np.array(arr['windSpeed']) * units('knots'),\n",
" direction * units.degree)\n",
" \n",
" data['eastward_wind'], data['northward_wind'] = u, v\n",
" data['present_weather'] = arr['presWeather']\n",
"\n",
" \n",
" # metars uses 'stationName' for its identifier and temps are in deg C\n",
" # metars also has sky coverage\n",
" if datatype == \"obs\":\n",
" data['stid'] = np.array(arr['stationName'])\n",
" data['air_temperature'] = tmp * units.degC\n",
" data['dew_point_temperature'] = dpt * units.degC\n",
" data['cloud_coverage'] = [int(get_cloud_cover(x)) for x in arr['skyCover']]\n",
" \n",
" # synoptic obs uses 'stationId', and temps are in Kelvin\n",
" elif datatype == \"sfcobs\":\n",
" data['stid'] = np.array(arr['stationId'])\n",
" data['air_temperature'] = tmp * units.kelvin\n",
" data['dew_point_temperature'] = dpt * units.kelvin\n",
" \n",
" return data"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a href=\"#top\">Top</a>\n",
"\n",
"---"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Function: plot_data()\n",
"\n",
2022-11-18 12:21:53 -07:00
"This function makes use of Metpy.StationPlotLayout and Metpy.StationPlot to add all surface observation data to our plot. The logic is very similar for both METAR and Synoptic data, so a `datatype` argument is used to distinguish between which data is being drawn, and then draws the appropriate features.\n",
2022-11-11 13:02:19 -07:00
"\n",
"This function plots:\n",
"- Wind barbs\n",
"- Air temperature\n",
"- Dew point temperature\n",
"- Precipitation\n",
"- Cloud coverage (for METARS)"
]
},
{
"cell_type": "code",
2025-02-12 17:02:03 -07:00
"execution_count": 5,
2022-11-11 13:02:19 -07:00
"metadata": {},
"outputs": [],
"source": [
"def plot_data(data, title, axes, datatype):\n",
" custom_layout = StationPlotLayout()\n",
" custom_layout.add_barb('eastward_wind', 'northward_wind', units='knots')\n",
" custom_layout.add_value('NW', 'air_temperature', fmt='.0f', units='degF', color='darkred')\n",
" custom_layout.add_value('SW', 'dew_point_temperature', fmt='.0f', units='degF', color='darkgreen')\n",
" custom_layout.add_value('E', 'precipitation', fmt='0.1f', units='inch', color='blue')\n",
" # metars has sky coverage\n",
" if datatype == 'obs':\n",
" custom_layout.add_symbol('C', 'cloud_coverage', sky_cover)\n",
" axes.set_title(title)\n",
" stationplot = StationPlot(axes, data['longitude'], data['latitude'], clip_on=True,\n",
" transform=ccrs.PlateCarree(), fontsize=10)\n",
" custom_layout.plot(stationplot, data)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a href=\"#top\">Top</a>\n",
"\n",
"---"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Initial Setup\n",
"\n",
"Connect to an EDEX server and define several [new data request objects](http://unidata.github.io/python-awips/api/IDataRequest.html).\n",
"\n",
"In this example we're using multiple different datatypes from EDEX, so we'll create a request object for each of the following:\n",
"- [The states outlines (datatype **maps**)](#Define-Maps-Request)\n",
"- [The METAR data (datatype **obs**)](#Define-METAR-Request)\n",
"- [The Synoptic data (datatype **sfc**)](#Define-Synoptic-Request)\n",
"\n",
"Some of the request use filters, so we'll also create several filters than can be used for the various data requests as well."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Initial EDEX Connection\n",
"\n",
"First we establish a connection to Unidata's public EDEX server."
]
},
{
"cell_type": "code",
2025-02-12 17:02:03 -07:00
"execution_count": 6,
2022-11-11 13:02:19 -07:00
"metadata": {},
"outputs": [],
"source": [
"# EDEX connection\n",
2025-02-13 13:04:21 -07:00
"edexServer = \"edex-cloud.unidata.ucar.edu\"\n",
2022-11-11 13:02:19 -07:00
"DataAccessLayer.changeEDEXHost(edexServer)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Maps Request and Response\n",
"The maps data request will give us data to draw our state outlines of interest (Florida and its neighboring states). We will retrieve the data response object here so we can create a geographic filter for the METAR and Synoptic data requests."
]
},
{
"cell_type": "code",
2025-02-12 17:02:03 -07:00
"execution_count": 7,
2022-11-11 13:02:19 -07:00
"metadata": {
"scrolled": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Found 6 MultiPolygons\n"
]
}
],
"source": [
"# Define the maps request\n",
"maps_request = DataAccessLayer.newDataRequest('maps')\n",
"# filter for multiple states\n",
"maps_request.addIdentifier('table', 'mapdata.states')\n",
"maps_request.addIdentifier('geomField', 'the_geom')\n",
"maps_request.addIdentifier('inLocation', 'true')\n",
"maps_request.addIdentifier('locationField', 'state')\n",
"maps_request.setParameters('state','name','lat','lon')\n",
"maps_request.setLocationNames('FL','GA','MS','AL','SC','LA')\n",
"maps_response = DataAccessLayer.getGeometryData(maps_request)\n",
"print(\"Found \" + str(len(maps_response)) + \" MultiPolygons\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Define Geographic Filter\n",
"\n",
"The previous EDEX request limited the data by using a **parameter** for the maps database called **state**. We can take the results from that filter and get a geographic **envelope** based on the Florida polygon that was returned from the previous cell.\n",
"\n",
"<br>\n",
"<div class=\"alert-warning\">\n",
" <b>Note:</b> Without such a filter you may be requesting many tens of thousands of records.\n",
"</div>\n"
]
},
{
"cell_type": "code",
2025-02-12 17:02:03 -07:00
"execution_count": 8,
2022-11-11 13:02:19 -07:00
"metadata": {},
2018-10-11 11:59:44 -06:00
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Florida FL 28.67402 -82.50934\n",
"Georgia GA 32.65155 -83.44848\n",
"Louisiana LA 31.0891 -92.02905\n",
"Alabama AL 32.79354 -86.82676\n",
"Mississippi MS 32.75201 -89.66553\n",
2022-11-11 13:02:19 -07:00
"South Carolina SC 33.93574 -80.89899\n",
2025-01-23 14:31:31 -07:00
"POLYGON ((-90.63429260299995 23.021051616000022, -90.63429260299995 32.50101280200016, -77.03199876199994 32.50101280200016, -77.03199876199994 23.021051616000022, -90.63429260299995 23.021051616000022))\n"
2018-10-11 11:59:44 -06:00
]
}
],
"source": [
"# Append each geometry to a numpy array\n",
"states = np.array([])\n",
2022-11-11 13:02:19 -07:00
"for ob in maps_response:\n",
2018-10-11 11:59:44 -06:00
" print(ob.getString('name'), ob.getString('state'), ob.getNumber('lat'), ob.getNumber('lon'))\n",
2022-11-11 13:02:19 -07:00
" states = np.append(states,ob.getGeometry())\n",
" # if this is Florida grab geographic info\n",
" if ob.getString('name') == \"Florida\":\n",
" bounds = ob.getGeometry().bounds\n",
" fl_lat = ob.getNumber('lat')\n",
" fl_lon = ob.getNumber('lon')\n",
"\n",
"if bounds is None:\n",
" print(\"Error, no record found for Florida!\")\n",
"\n",
"else: \n",
" # buffer our bounds by +/i degrees lat/lon\n",
" bbox=[bounds[0]-3,bounds[2]+3,bounds[1]-1.5,bounds[3]+1.5]\n",
"\n",
" # Create envelope geometry\n",
" envelope = Polygon([(bbox[0],bbox[2]),(bbox[0],bbox[3]),\n",
" (bbox[1], bbox[3]),(bbox[1],bbox[2]),\n",
" (bbox[0],bbox[2])])\n",
" \n",
"print(envelope)"
2018-10-11 11:59:44 -06:00
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
2022-11-11 13:02:19 -07:00
"### Define Time Filter\n",
"\n",
"Both the METAR and Synoptic datasets should be filtered by time to avoid requesting an unreasonable amount of data. By defining one filter now, we can use it in both of their data requests to EDEX.\n",
"\n",
"<br>\n",
"<div class=\"alert-info\">\n",
" <b>Note:</b> Here we will use the most recent hour as our default filter. Try adjusting the timerange and see the difference in the final plots.\n",
"</div>"
2018-10-11 11:59:44 -06:00
]
},
{
"cell_type": "code",
2025-02-12 17:02:03 -07:00
"execution_count": 9,
2018-10-11 11:59:44 -06:00
"metadata": {},
"outputs": [
{
2022-11-11 13:02:19 -07:00
"name": "stdout",
"output_type": "stream",
"text": [
2025-02-12 17:02:03 -07:00
"(Feb 12 25 22:57:17 , Feb 12 25 23:57:17 )\n"
2022-11-11 13:02:19 -07:00
]
2018-10-11 11:59:44 -06:00
}
],
"source": [
2022-11-11 13:02:19 -07:00
"# Filter for the last hour\n",
2025-01-23 14:31:31 -07:00
"lastHourDateTime = datetime.now(UTC) - timedelta(minutes = 60)\n",
2022-11-11 13:02:19 -07:00
"start = lastHourDateTime.strftime('%Y-%m-%d %H:%M:%S')\n",
2025-01-23 14:31:31 -07:00
"end = datetime.now(UTC).strftime('%Y-%m-%d %H:%M:%S')\n",
2018-10-11 11:59:44 -06:00
"\n",
2022-11-11 13:02:19 -07:00
"beginRange = datetime.strptime( start , \"%Y-%m-%d %H:%M:%S\")\n",
"endRange = datetime.strptime( end , \"%Y-%m-%d %H:%M:%S\")\n",
"timerange = TimeRange(beginRange, endRange)\n",
2018-10-11 11:59:44 -06:00
"\n",
2022-11-11 13:02:19 -07:00
"print(timerange)"
2018-10-11 11:59:44 -06:00
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
2022-11-11 13:02:19 -07:00
"### Define Common Parameters for Data Requests\n",
2018-10-11 13:36:14 -06:00
"\n",
2022-11-11 13:02:19 -07:00
"METAR obs and Synoptic obs share several of the same parameters. By defining them here, they can be reused for both of the requests and this makes our code more efficient."
]
},
{
"cell_type": "code",
2025-02-12 17:02:03 -07:00
"execution_count": 10,
2022-11-11 13:02:19 -07:00
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"['timeObs', 'longitude', 'latitude', 'temperature', 'dewpoint', 'windDir', 'windSpeed', 'seaLevelPress', 'presWeather', 'skyLayerBase']\n"
]
}
],
"source": [
"shared_params = [\"timeObs\", \"longitude\", \"latitude\", \"temperature\",\n",
" \"dewpoint\", \"windDir\", \"windSpeed\", \"seaLevelPress\",\n",
" \"presWeather\", \"skyLayerBase\"]\n",
"print(shared_params)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Define METAR Request\n",
2018-10-11 11:59:44 -06:00
"\n",
2022-11-11 13:02:19 -07:00
"To get METAR data we must use the **obs** datatype. To help limit the amount of data returned, we will narrow the request by using a geographic **envelope**, setting the request **parameters**, and using **timerange** as a time filter."
2018-10-11 11:59:44 -06:00
]
},
{
"cell_type": "code",
2025-02-12 17:02:03 -07:00
"execution_count": 11,
2018-10-11 11:59:44 -06:00
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
2025-02-12 17:02:03 -07:00
"DefaultDataRequest(datatype=obs, identifiers={}, parameters=['timeObs', 'longitude', 'latitude', 'temperature', 'dewpoint', 'windDir', 'windSpeed', 'seaLevelPress', 'presWeather', 'skyLayerBase', 'stationName', 'skyCover'], levels=[], locationNames=[], envelope=<dynamicserialize.dstypes.org.locationtech.jts.geom.Envelope.Envelope object at 0x7f3424495be0>)\n"
2018-10-11 11:59:44 -06:00
]
}
],
"source": [
2022-11-11 13:02:19 -07:00
"# New metar request\n",
"metar_request = DataAccessLayer.newDataRequest(\"obs\", envelope=envelope)\n",
2018-10-11 11:59:44 -06:00
"\n",
2022-11-11 13:02:19 -07:00
"# metar specifc parameters\n",
"metar_params = [\"stationName\", \"skyCover\"]\n",
"# combine all parameters\n",
"all_metar_params = shared_params + metar_params\n",
"# set the parameters on the metar request\n",
"metar_request.setParameters(*(all_metar_params))\n",
"\n",
"print(metar_request)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Define Synoptic Request\n",
"\n",
"Similar to the request above, we will limit the amount of data returned by using a geographic **envelope**, setting the request **parameters**, and using **timerange** as a time filter.\n",
"\n",
"However, in order to access synoptic observations we will use the **sfcobs** datatype."
]
},
{
"cell_type": "code",
2025-02-12 17:02:03 -07:00
"execution_count": 12,
2022-11-11 13:02:19 -07:00
"metadata": {
"scrolled": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
2025-02-12 17:02:03 -07:00
"DefaultDataRequest(datatype=sfcobs, identifiers={}, parameters=['timeObs', 'longitude', 'latitude', 'temperature', 'dewpoint', 'windDir', 'windSpeed', 'seaLevelPress', 'presWeather', 'skyLayerBase', 'stationId'], levels=[], locationNames=[], envelope=<dynamicserialize.dstypes.org.locationtech.jts.geom.Envelope.Envelope object at 0x7f33d7429590>)\n"
2022-11-11 13:02:19 -07:00
]
}
],
"source": [
"# New sfcobs/SYNOP request\n",
"syn_request = DataAccessLayer.newDataRequest(\"sfcobs\", envelope=envelope)\n",
"\n",
"# (sfcobs) uses stationId, while (obs) uses stationName\n",
"syn_params = [\"stationId\"]\n",
"# combine all parameters\n",
"all_syn_params = shared_params + syn_params\n",
"# set the parameters on the synoptic request\n",
"syn_request.setParameters(*(all_syn_params))\n",
"\n",
"print(syn_request)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a href=\"#top\">Top</a>\n",
"\n",
"---"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Get the Data!\n",
"\n",
"We have already obtained our maps data, but we still have to collect our observation data."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Get the EDEX Responses"
]
},
{
"cell_type": "code",
2025-02-12 17:02:03 -07:00
"execution_count": 13,
2022-11-11 13:02:19 -07:00
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
2025-02-12 17:02:03 -07:00
"Found 3036 METAR records\n",
"\tUsing 146 temperature records\n",
"Found 254 Synoptic records\n",
"\tUsing 103 temperature records\n"
2022-11-11 13:02:19 -07:00
]
}
],
"source": [
"# METARs data\n",
"metar_response = DataAccessLayer.getGeometryData(metar_request,timerange)\n",
2018-10-11 11:59:44 -06:00
"# function getMetarObs was added in python-awips 18.1.4\n",
2022-11-11 13:02:19 -07:00
"metars = DataAccessLayer.getMetarObs(metar_response)\n",
"print(\"Found \" + str(len(metar_response)) + \" METAR records\")\n",
"print(\"\\tUsing \" + str(len(metars['temperature'])) + \" temperature records\")\n",
"\n",
"# Synoptic data\n",
"syn_response = DataAccessLayer.getGeometryData(syn_request,timerange)\n",
"# function getSynopticObs was added in python-awips 18.1.4\n",
"synoptic = DataAccessLayer.getSynopticObs(syn_response)\n",
"print(\"Found \" + str(len(syn_response)) + \" Synoptic records\")\n",
"print(\"\\tUsing \" + str(len(synoptic['temperature'])) + \" temperature records\")"
2018-10-11 11:59:44 -06:00
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
2022-11-11 13:02:19 -07:00
"### Extract Plotting Data"
]
},
{
"cell_type": "code",
2025-02-12 17:02:03 -07:00
"execution_count": 14,
2022-11-11 13:02:19 -07:00
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
2025-02-12 17:02:03 -07:00
"146 METARs stations\n",
"103 Synoptic stations\n"
2022-11-11 13:02:19 -07:00
]
}
],
"source": [
"# Pull all necessary plotting information for the metar data\n",
"metars_data = extract_plotting_data(metars, 'obs')\n",
"print(str(len(metars_data['stid'])) + \" METARs stations\")\n",
2018-10-11 11:59:44 -06:00
"\n",
2022-11-11 13:02:19 -07:00
"# Pull all necessary plotting information for the synoptic data\n",
"synoptic_data = extract_plotting_data(synoptic, 'sfcobs')\n",
"print(str(len(synoptic_data['stid'])) + \" Synoptic stations\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a href=\"#top\">Top</a>\n",
"\n",
"---"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Plot the Data\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Draw the Region\n",
"\n",
"Here we will draw our region by using the **states** polygons we retreived from EDEX [earlier in this example](#Maps-Request-and-Response). To create this plot we use the [make_map()](#Function:-make_map()) function which also adds lines of latitude and longitude for additional context."
2018-10-11 11:59:44 -06:00
]
},
{
"cell_type": "code",
2025-02-12 17:02:03 -07:00
"execution_count": 15,
2018-10-11 11:59:44 -06:00
"metadata": {},
2018-10-11 13:36:14 -06:00
"outputs": [
{
"data": {
"text/plain": [
2025-02-12 17:02:03 -07:00
"<cartopy.mpl.feature_artist.FeatureArtist at 0x7f33d6856510>"
2018-10-11 13:36:14 -06:00
]
},
2025-02-12 17:02:03 -07:00
"execution_count": 15,
2018-10-11 13:36:14 -06:00
"metadata": {},
"output_type": "execute_result"
2022-11-11 13:02:19 -07:00
},
{
"data": {
2025-01-23 14:31:31 -07:00
"image/png": "iVBORw0KGgoAAAANSUhEUgAABSMAAAOJCAYAAADm4TcOAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlHJYcgAAAAlwSFlzAAAPYQAAD2EBqD+naQABAABJREFUeJzs3Xd8U9X/P/BX0r1paUtp2aXsvZfIEmSJqAiKDEX2UOQjAoo4kKUoigKCIjJEQECmyBIZMsreZa/S0r1X0pzfH/xyv7lN2iZt0tvxej4eeXjuOvedeEiTd85QCSEEiIiIiIiIiIiIiGxMrXQAREREREREREREVDYwGUlERERERERERERFgslIIiIiIiIiIiIiKhJMRhIREREREREREVGRYDKSiIiIiIiIiIiIigSTkURERERERERERFQkmIwkIiIiIiIiIiKiIsFkJBERERERERERERUJe6UDKA4yMjKQlZWldBhEREREREREREQlkqOjI5ydnfM9r8wnIzMyMlC9enVERkYqHQoREREREREREVGJFBAQgLt37+abkCzzycisrCxERkbi4cOH8PT0VDocm9HpdIiOjoafnx/Uao7OJ8sNGTIE27dvBwAMHjwYS5YsUTgitmsqvdi2i0ZKSgqCgoIAAC4uLvxh0sbYrqk0Yrs2bdu2bRg+fDh0Oh0AQK1WY+zYsZg6dSrKlSunbHBFIDExEcOGDcM///xj1XpHjx6NOXPmwN7e9l/j2bapNGK7tq2kpCRUrlwZWVlZTEaay9PTs9QnIzMyMuDp6cl/dFQgjx8/lspNmzYtFv9e2K6ptGLbLhrr1q2Tyl5eXsXifa00Y7um0ojt2rQhQ4bA09MTr7zyCrRaLXQ6HX744QesW7cO8fHxSodnc56enjh48CASExPRsGFDPHz4UHb8zp07qF69Ovr3748///zT6Prdu3cjLS0NAwcORHZ2trSvZ8+eRRE+ALZtKp3YrosPvvpEZJbo6Gip3KBBAwUjISKyDq1WK5Xj4+OxcOFC2T4iIiq4fv364aeffpLtS0hIkHpLlgVeXl548OABunbtKu379ttvUb16dQDA3LlzUatWLZQrVw6dOnXCggUL8Pbbb+Ojjz7CypUrcfXqVaxevRoJCQlFmogkIrI19owkIrMkJiZK5fr16ysYCRGRdQwePBiTJk0CAGRmZuJ///sf5s6di8jIyCIZAkdEVNotXLhQtm1nZ1cmeyMZ9ow8duyY9LenTp06CAsLk52rUqmk8tGjR5GQkCDbR0RUGpS9vwREVCApKSlSuVKlSgpGQkRkHT4+Ppg6darsS15sbCy++OILBaMiIio9bty4IduOiYlRKBJl7dq1Sypv3LgR169fz/VcPz8/qZyUlCSbKomIqLRgMpKI8qXVaqWhi/lNREtEVJLMnz8fd+/ele3bvHmzQtEQEZUutWvXlsqenp5lYvEaU2rWrIkZM2ZI223btsWuXbuQlZVldK5h8nHYsGEICAgokhiJiIoSk5FElK/z589LZS7wQESlzfvvvy/b9vf3VygSIqLS5a233pLKSUlJGDt2rILRKGvcuHFSOSEhAX369IGTkxPu378vO8/e3h5CCAghsGrVKtjZ2RV1qERENsdkJBHlKzQ0VCrz11kiKm22bt0q296+fbtCkRARlS7vvPMO2rRpI20vW7YMn376qYIRKScoKMjk/mrVqpWpRX2IiAAmI4nIDBcvXpTK1apVUy4QIiIrO336tNEK2mV1TjMiIls4duwYQkJCpO1PPvlEuWCIiKhYYDKSiPJlOMl2vXr1FIyEiMi6tm3bZrTP19dXgUiIiEontVqNOXPmyPZduXJFoWiKJ66WTURlDZORRJSv27dvS+X27dsrGAkRkXU1bNhQtu3s7AxXV1eFoiEiKp2qVq0q227QoIFCkSirRYsWRvsmTpzIZCQRlTlMRhJRvuLi4qRyx44dFYyEiMh67t69a7SYwpo1axSKhoio9GrZsqXRVD8qlQoNGzYsU/MlLlmyRLatUqkwfvx4haIhIlIOk5FElK/09HQAT4fZcDVtIiot2rRpI/uxZdKkSXjllVcUjIiIqPTau3ev0b7Lly8jICAAGRkZCkRU9Fq2bCnb7tGjB2rXrq1QNEREymEykojylJSUJP1i7eLionA0RETWcfr0aURFRUnb7733Hr799lsFIyIiKt1CQkIQGhpqtD86OhqbN29WIKKit3DhQtn21atXFYqEiEhZTEYSUZ5Onz4tlX18fBSMhIjIetRq+UegH374Ab1798b58+eVCYiIqAxo0aIF5syZA3t7e9n+WrVqKRRR0UhISMA333yD//3vf7L9Dx48QFpamkJREREph8lIIsrTxYsXpbK/v7+CkRARWU+TJk1k005kZmZi9+7daNq0KcqXL49XX30Vjx8/VjBCIqLSafr06YiOjpbtmzx5skLR2Nbhw4ehUqng7e2N9957z+Q5Bw8eLOKoiIiUx2QkEeXpypUrUjnnSohERCWVWq3GxYsX0bFjR7i7u8uOxcXFYdOmTahcuTK2bdumUIRERKVXuXLl4OzsLG0fO3ZMwWjyJ4TAxIkT0bFjR7MWOgsNDUWXLl3w7LPPGh3TP+8qVaoAAOrXr2/dYImISgAmI4koT3fu3JHKnGCbiEqTqlWr4t9//0VycjL279+P9u3by4YO6nQ6vPLKK9i+fbuCURIRlU7Lli2TbSclJSkUSf7Onz+P77//HkeOHMHQoUNlI4cMXbp0Ce3atUOrVq3wzz//yI41a9YMly9fRnp6OlauXIlKlSrh9OnTqF69elE8BSKiYoXJSCLKU3h4uFTmL7dEVFp17doVR48eRWZmJtauXSst2KXVatGvXz906NABWVlZCkdJRFQ6REZGYsyYMbJ9t27dUiia/OWMrXHjxkhISMBXX30FlUoFZ2dnqFQqNGrUCMePH5fOq1mzJhYuXIjLly/jzJkz0mfpN998E8eOHUPz5s2L9HkQERUX9vmfQkRlWUxMjFRu0aKFgpEQEdmeWq3G4MGDUatWLTzzzDPIzMwE8HQIYYUKFXD79m0u5kVEVEjVq1dHRkaGbF+zZs0UiiZ/pnptent7S2X93wpD8+bNw3vvvQcHBwebxkZEVBKxZyQR5Sk5OVkqh4SEKBgJEVHRqV27ttHqrgkJCfjwww8VioiIqHS4f/++USJy7ty5CkVjHl9fX7POq169Ojp37owHDx7ggw8+YCKSiCgX7BlJRLnS6XTSsEQHBweo1fz9gojKhmHDhuHSpUtG+zmkjoiocBo3bizb/vfff9GxY0eFojFPzZo1cz22ceNGvPzyy9DpdLJ5h4mIKHfMLBBRri5fviyVvby8FIyEiKhopaamGu1bsWIF3n77bQWiISIqPVJSUmTbSiQijxw5ApVKhdq1a+P27dv5nq/T6Uzu//PPPzFgwACo1WomIomILMB3TCLK1b///iuVAwMDFYyEiMi2xo8fj19//RXA03kjDaeoAJ4mJ11dXZUIjYioVFGr1cjOzpa279+/j6pVq9r0njt27MC1a9fQoUMHNGrUCF27dgUA3LhxAzVr1sTjx49RsWJFk9cmJiaiUaNGJo/16NHDZjETEZVmTEYSUa6uXLkilfMankJEVJJ9/PHHWLJkSa7Hf/zxRyYiiYispFGjRjhz5oy0XaNGDdy9exdVqlSxyf0OHjyIF154Ic9zDJOjho4dO5brtf369YOzs3Oh4yMiKos4TJuIcmU4bCU4OFjBSIiIbGfr1q0m96tUKvTr1w+jRo0q4oiIiEqvZcuWoXr16tK2TqdD1apVZT+CW1NcXFy+5xiujK33119/oVOnTkbXlytXDsuXL8eWLVusFiMRUVnDZCQR5erhw4dSOedk40REJd2iRYvQsmVL2fy4AODm5obY2FjodDr8+eefygRHRFRKtWjRAnfu3MG0adNk+998802b3K93797o1KlTnufk7P1+8eJFDBw4EFqtVra/W7duuHbtGkaOHMmFHYmICoHvoESUq6ioKKncpk0bBSMhIrKuPn36YPLkyTh9+rTRsVGjRsHHx0eBqIiIyo6
2022-11-11 13:02:19 -07:00
"text/plain": [
2025-01-23 14:31:31 -07:00
"<Figure size 1600x1200 with 1 Axes>"
2022-11-11 13:02:19 -07:00
]
},
2025-01-23 14:31:31 -07:00
"metadata": {},
2022-11-11 13:02:19 -07:00
"output_type": "display_data"
2018-10-11 13:36:14 -06:00
}
],
2018-10-11 11:59:44 -06:00
"source": [
2022-11-11 13:02:19 -07:00
"# Create the figure and axes used for the plot\n",
"fig, ax = make_map(bbox=bbox)\n",
"# Create a feature based off our states polygons\n",
"shape_feature = ShapelyFeature(states,ccrs.PlateCarree(), \n",
" facecolor='none', linestyle=\"-\",edgecolor='#000000',linewidth=2)\n",
"ax.add_feature(shape_feature)"
2018-10-11 11:59:44 -06:00
]
},
2018-10-11 13:36:14 -06:00
{
"cell_type": "markdown",
"metadata": {},
"source": [
2022-11-11 13:02:19 -07:00
"### Plot METAR Data\n",
2018-10-11 13:36:14 -06:00
"\n",
2022-11-11 13:02:19 -07:00
"On the same axes (**ax**) and figure (**fig**) plot the METAR data."
2018-10-11 13:36:14 -06:00
]
},
2018-10-11 11:59:44 -06:00
{
"cell_type": "code",
2025-02-12 17:02:03 -07:00
"execution_count": 16,
2018-10-11 11:59:44 -06:00
"metadata": {},
"outputs": [
{
2022-11-11 13:02:19 -07:00
"data": {
2025-02-12 17:02:03 -07:00
"image/png": "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
2022-11-11 13:02:19 -07:00
"text/plain": [
2025-01-23 14:31:31 -07:00
"<Figure size 1600x1200 with 1 Axes>"
2022-11-11 13:02:19 -07:00
]
},
2025-02-12 17:02:03 -07:00
"execution_count": 16,
2022-11-11 13:02:19 -07:00
"metadata": {},
"output_type": "execute_result"
2018-10-11 11:59:44 -06:00
}
],
"source": [
2022-11-11 13:02:19 -07:00
"# Create a title for the plot\n",
"title = str(metar_response[-1].getDataTime()) + \" | METAR Surface Obs | \" + edexServer\n",
"# Plot the station information for METARs data\n",
"plot_data(metars_data, title, ax, 'obs')\n",
"# Display the figure\n",
"fig"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
2022-11-15 10:06:17 -07:00
"### Plot Synoptic Data\n",
2018-10-11 11:59:44 -06:00
"\n",
2022-11-11 13:02:19 -07:00
"On a new axes and figure (**ax_syn**, **fig_syn**) plot the map and synoptic data."
2018-10-11 11:59:44 -06:00
]
},
{
"cell_type": "code",
2025-02-12 17:02:03 -07:00
"execution_count": 17,
2018-10-11 11:59:44 -06:00
"metadata": {},
2018-10-11 13:36:14 -06:00
"outputs": [
{
"data": {
2025-02-12 17:02:03 -07:00
"image/png": "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
2018-10-11 13:36:14 -06:00
"text/plain": [
2025-01-23 14:31:31 -07:00
"<Figure size 1600x1200 with 1 Axes>"
2018-10-11 13:36:14 -06:00
]
},
2025-01-23 14:31:31 -07:00
"metadata": {},
2018-10-11 13:36:14 -06:00
"output_type": "display_data"
}
],
2018-10-11 11:59:44 -06:00
"source": [
2022-11-11 13:02:19 -07:00
"# Create a new figure and axes for the synoptic data\n",
"fig_syn, ax_syn = make_map(bbox=bbox)\n",
"# Create the states feature from the polygons\n",
2018-10-11 13:36:14 -06:00
"shape_feature = ShapelyFeature(states,ccrs.PlateCarree(), \n",
" facecolor='none', linestyle=\"-\",edgecolor='#000000',linewidth=2)\n",
2022-11-11 13:02:19 -07:00
"ax_syn.add_feature(shape_feature)\n",
"# Create a title for the figure\n",
"title = str(syn_response[-1].getDataTime()) + \" | SYNOP Surface Obs | \" + edexServer\n",
"# Draw the synoptic data\n",
"plot_data(synoptic_data, title, ax_syn, 'sfcobs')"
2018-10-11 13:36:14 -06:00
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
2022-11-11 13:02:19 -07:00
"### Plot both METAR and Synoptic Data\n",
2018-10-11 13:36:14 -06:00
"\n",
2022-11-11 13:02:19 -07:00
"Add the synoptic data to our first axes and figure (**ax**, **fig**) that already contains our map and METARs data."
2018-10-11 11:59:44 -06:00
]
},
{
"cell_type": "code",
2025-02-12 17:02:03 -07:00
"execution_count": 18,
2018-10-11 11:59:44 -06:00
"metadata": {},
"outputs": [
{
"data": {
2025-02-12 17:02:03 -07:00
"image/png": "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
2018-10-11 11:59:44 -06:00
"text/plain": [
2025-01-23 14:31:31 -07:00
"<Figure size 1600x1200 with 1 Axes>"
2018-10-11 11:59:44 -06:00
]
},
2025-02-12 17:02:03 -07:00
"execution_count": 18,
2018-10-11 11:59:44 -06:00
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
2022-11-11 13:02:19 -07:00
"# Create a title for both the METAR and Synopotic data\n",
"title = str(syn_response[-1].getDataTime()) + \" | METAR & Synoptic Surface Obs | \" + edexServer\n",
"# Draw the synoptic on the first axes that already has the metar data\n",
"plot_data(synoptic_data, title, ax, 'sfcobs')\n",
"# Display the figure\n",
2018-10-11 11:59:44 -06:00
"fig"
]
2022-11-11 13:02:19 -07:00
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a href=\"#top\">Top</a>\n",
"\n",
"---"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## See Also\n",
"\n",
"- [Aviation Weather Center Static METAR Plots Information](https://www.aviationweather.gov/metar/help?page=plot)\n",
"\n",
"### Related Notebooks\n",
"\n",
"- [Metar Station Plot with MetPy](http://unidata.github.io/python-awips/examples/generated/METAR_Station_Plot_with_MetPy.html)\n",
"- [Map Resources and Topography](http://unidata.github.io/python-awips/examples/generated/Map_Resources_and_Topography.html)\n",
"\n",
"### Additional Documentation\n",
"\n",
"**python-awips:**\n",
"\n",
"- [DataAccessLayer.changeEDEXHost()](http://unidata.github.io/python-awips/api/DataAccessLayer.html#awips.dataaccess.DataAccessLayer.changeEDEXHost)\n",
"- [DataAccessLayer.newDataRequest()](http://unidata.github.io/python-awips/api/DataAccessLayer.html#awips.dataaccess.DataAccessLayer.newDataRequest)\n",
"- [IDataRequest](http://unidata.github.io/python-awips/api/IDataRequest.html)\n",
"- [DataAccessLayer.getGeometryData](http://unidata.github.io/python-awips/api/PyGeometryData.html)\n",
"\n",
"**datetime:**\n",
"\n",
"- [datetime.datetime](https://docs.python.org/3/library/datetime.html#datetime-objects)\n",
2025-01-23 14:31:31 -07:00
"- [datetime.now(UTC)](https://docs.python.org/3/library/datetime.html?#datetime.datetime.utcnow)\n",
2022-11-11 13:02:19 -07:00
"- [datetime.timedelta](https://docs.python.org/3/library/datetime.html#timedelta-objects)\n",
"- [datetime.strftime() and datetime.strptime()](https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior)\n",
"\n",
"**numpy:**\n",
"\n",
"- [np.array](https://numpy.org/doc/stable/reference/generated/numpy.array.html)\n",
"\n",
"**cartopy:**\n",
"\n",
"- [cartopy projection list](https://scitools.org.uk/cartopy/docs/v0.14/crs/projections.html?#cartopy-projection-list)\n",
"\n",
"**matplotlib:**\n",
"\n",
"- [matplotlib.pyplot()](https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.html)\n",
"- [matplotlib.pyplot.figure()](https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.figure.html)\n",
"- [ax.set_extent](https://matplotlib.org/stable/api/image_api.html?highlight=set_extent#matplotlib.image.AxesImage.set_extent)\n",
"- [ax.set_title](https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.set_title.html)\n",
"\n",
"\n",
"**metpy:**\n",
"\n",
"- [metpy.calc.wind_components](https://unidata.github.io/MetPy/latest/api/generated/metpy.calc.wind_components.html)\n",
"- [metpy.plots.StationPlot()](https://unidata.github.io/MetPy/latest/api/generated/metpy.plots.StationPlot.html)\n",
"- [metpy.plots.StationPlotLayout()](https://unidata.github.io/MetPy/latest/api/generated/metpy.plots.StationPlotLayout.html)\n",
"- [metpy.units](https://unidata.github.io/MetPy/latest/api/generated/metpy.units.html)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a href=\"#top\">Top</a>\n",
"\n",
"---"
]
2018-10-11 11:59:44 -06:00
}
],
"metadata": {
"kernelspec": {
2023-08-24 12:49:20 -06:00
"display_name": "Python 3 (ipykernel)",
2018-10-11 11:59:44 -06:00
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
2025-01-23 14:31:31 -07:00
"version": "3.13.1"
2022-08-18 15:59:45 -07:00
},
"toc": {
"base_numbering": 1,
"nav_menu": {},
"number_sections": true,
"sideBar": true,
2022-11-11 13:02:19 -07:00
"skip_h1_title": true,
2022-08-18 15:59:45 -07:00
"title_cell": "Table of Contents",
"title_sidebar": "Contents",
2022-11-11 13:02:19 -07:00
"toc_cell": true,
2022-08-18 15:59:45 -07:00
"toc_position": {},
"toc_section_display": true,
2022-11-11 13:02:19 -07:00
"toc_window_display": true
2018-10-11 11:59:44 -06:00
}
},
"nbformat": 4,
2025-01-23 14:31:31 -07:00
"nbformat_minor": 4
2018-10-11 11:59:44 -06:00
}