python-awips/examples/notebooks/Regional_Surface_Obs_Plot.ipynb

469 lines
584 KiB
Text
Raw Normal View History

{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"%matplotlib inline"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This exercise creates a surface observsation station plot for the state of Florida, using both METAR (datatype *obs*) and Synoptic (datatype *sfcobs*). Because we are using the AWIPS Map Database for state and county boundaries, there is no use of Cartopy `cfeature` in this exercise."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"from awips.dataaccess import DataAccessLayer\n",
"from dynamicserialize.dstypes.com.raytheon.uf.common.time import TimeRange\n",
"from datetime import datetime, timedelta\n",
"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",
"from shapely.geometry import Polygon\n",
"import matplotlib.pyplot as plt\n",
"from metpy.units import units\n",
"from metpy.calc import wind_components\n",
"from metpy.plots import simple_layout, StationPlot, StationPlotLayout\n",
"import warnings\n",
"\n",
"def get_cloud_cover(code):\n",
" if 'OVC' in code:\n",
" return 1.0\n",
" elif 'BKN' in code:\n",
" return 6.0/8.0\n",
" elif 'SCT' in code:\n",
" return 4.0/8.0\n",
" elif 'FEW' in code:\n",
" return 2.0/8.0\n",
" else:\n",
" return 0"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Found 1 MultiPolygon\n",
"Florida FL 28.67402 -82.50934 (-87.63429260299995, 24.521051616000022, -80.03199876199994, 31.001012802000048)\n",
"\n",
"Found 6 MultiPolygons\n",
"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",
"South Carolina SC 33.93574 -80.89899\n"
]
}
],
"source": [
"# EDEX request for a single state\n",
"edexServer = \"edex-cloud.unidata.ucar.edu\"\n",
"DataAccessLayer.changeEDEXHost(edexServer)\n",
"request = DataAccessLayer.newDataRequest('maps')\n",
"request.addIdentifier('table', 'mapdata.states')\n",
"request.addIdentifier('state', 'FL')\n",
"request.addIdentifier('geomField', 'the_geom')\n",
"request.setParameters('state','name','lat','lon')\n",
"response = DataAccessLayer.getGeometryData(request)\n",
"record = response[0]\n",
"print(\"Found \" + str(len(response)) + \" MultiPolygon\")\n",
"state={}\n",
"state['name'] = record.getString('name')\n",
"state['state'] = record.getString('state')\n",
"state['lat'] = record.getNumber('lat')\n",
"state['lon'] = record.getNumber('lon')\n",
"#state['geom'] = record.getGeometry()\n",
"state['bounds'] = record.getGeometry().bounds\n",
"print(state['name'], state['state'], state['lat'], state['lon'], state['bounds'])\n",
"print()\n",
"\n",
"# EDEX request for multiple states\n",
"request = DataAccessLayer.newDataRequest('maps')\n",
"request.addIdentifier('table', 'mapdata.states')\n",
"request.addIdentifier('geomField', 'the_geom')\n",
"request.addIdentifier('inLocation', 'true')\n",
"request.addIdentifier('locationField', 'state')\n",
"request.setParameters('state','name','lat','lon')\n",
"request.setLocationNames('FL','GA','MS','AL','SC','LA')\n",
"response = DataAccessLayer.getGeometryData(request)\n",
"print(\"Found \" + str(len(response)) + \" MultiPolygons\")\n",
"\n",
"# Append each geometry to a numpy array\n",
"states = np.array([])\n",
"for ob in response:\n",
" print(ob.getString('name'), ob.getString('state'), ob.getNumber('lat'), ob.getNumber('lon'))\n",
" states = np.append(states,ob.getGeometry())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now make sure we can plot the states with a lat/lon grid. "
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<cartopy.mpl.feature_artist.FeatureArtist at 0x11dcfedd8>"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 1152x864 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"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.xlabels_top = gl.ylabels_right = False\n",
" gl.xformatter = LONGITUDE_FORMATTER\n",
" gl.yformatter = LATITUDE_FORMATTER\n",
" return fig, ax\n",
"\n",
"# buffer our bounds by +/i degrees lat/lon\n",
"bounds = state['bounds']\n",
"bbox=[bounds[0]-3,bounds[2]+3,bounds[1]-1.5,bounds[3]+1.5]\n",
"\n",
"fig, ax = make_map(bbox=bbox)\n",
"shape_feature = ShapelyFeature(states,ccrs.PlateCarree(), \n",
" facecolor='none', linestyle=\"-\",edgecolor='#000000',linewidth=2)\n",
"ax.add_feature(shape_feature)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"\n",
"## Plot METAR (obs)\n",
"\n",
"Here we use a spatial envelope to limit the request to the boundary or our plot. Without such a filter you may be requesting many tens of thousands of records."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Found 3468 records\n",
"Using 152 temperature records\n"
]
}
],
"source": [
"# 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",
"# New obs request\n",
"DataAccessLayer.changeEDEXHost(edexServer)\n",
"request = DataAccessLayer.newDataRequest(\"obs\", envelope=envelope)\n",
"availableProducts = DataAccessLayer.getAvailableParameters(request)\n",
"single_value_params = [\"timeObs\", \"stationName\", \"longitude\", \"latitude\", \n",
" \"temperature\", \"dewpoint\", \"windDir\",\n",
" \"windSpeed\", \"seaLevelPress\"]\n",
"multi_value_params = [\"presWeather\", \"skyCover\", \"skyLayerBase\"]\n",
"params = single_value_params + multi_value_params\n",
"request.setParameters(*(params))\n",
"\n",
"# Time range\n",
"lastHourDateTime = datetime.utcnow() - timedelta(minutes = 60)\n",
"start = lastHourDateTime.strftime('%Y-%m-%d %H:%M:%S')\n",
"end = datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S')\n",
"\n",
"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",
"# Get response\n",
"response = DataAccessLayer.getGeometryData(request,timerange)\n",
"# function getMetarObs was added in python-awips 18.1.4\n",
"obs = DataAccessLayer.getMetarObs(response)\n",
"print(\"Found \" + str(len(response)) + \" records\")\n",
"print(\"Using \" + str(len(obs['temperature'])) + \" temperature records\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Next grab the simple variables out of the 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 fraction values to integer codes [0 - 8]\n",
"- Map METAR weather codes to WMO codes for weather symbols"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 1152x864 with 1 Axes>"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"data = dict()\n",
"data['stid'] = np.array(obs['stationName'])\n",
"data['latitude'] = np.array(obs['latitude'])\n",
"data['longitude'] = np.array(obs['longitude'])\n",
"tmp = np.array(obs['temperature'], dtype=float)\n",
"dpt = np.array(obs['dewpoint'], dtype=float)\n",
"\n",
"# Suppress nan masking warnings\n",
"warnings.filterwarnings(\"ignore\",category =RuntimeWarning)\n",
"\n",
"tmp[tmp == -9999.0] = 'nan'\n",
"dpt[dpt == -9999.] = 'nan' \n",
"data['air_temperature'] = tmp * units.degC\n",
"data['dew_point_temperature'] = dpt * units.degC\n",
"data['air_pressure_at_sea_level'] = np.array(obs['seaLevelPress'])* units('mbar')\n",
"direction = np.array(obs['windDir'])\n",
"direction[direction == -9999.0] = 'nan'\n",
"u, v = wind_components(np.array(obs['windSpeed']) * units('knots'),\n",
" direction * units.degree)\n",
"data['eastward_wind'], data['northward_wind'] = u, v\n",
"data['cloud_coverage'] = [int(get_cloud_cover(x)*8) for x in obs['skyCover']]\n",
"data['present_weather'] = obs['presWeather']\n",
"proj = ccrs.LambertConformal(central_longitude=state['lon'], central_latitude=state['lat'],\n",
" standard_parallels=[35])\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",
"ax.set_title(str(response[-1].getDataTime()) + \" | METAR Surface Obs | \" + edexServer)\n",
"stationplot = StationPlot(ax, data['longitude'], data['latitude'], clip_on=True,\n",
" transform=ccrs.PlateCarree(), fontsize=10)\n",
"custom_layout.plot(stationplot, data)\n",
"fig"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"\n",
"## Plot Synoptic (sfcobs)"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Found 260 records\n",
"Using 78 temperature records\n"
]
}
],
"source": [
"# New sfcobs/SYNOP request\n",
"DataAccessLayer.changeEDEXHost(edexServer)\n",
"request = DataAccessLayer.newDataRequest(\"sfcobs\", envelope=envelope)\n",
"availableProducts = DataAccessLayer.getAvailableParameters(request)\n",
"# (sfcobs) uses stationId, while (obs) uses stationName,\n",
"# the rest of these parameters are the same.\n",
"single_value_params = [\"timeObs\", \"stationId\", \"longitude\", \"latitude\", \n",
" \"temperature\", \"dewpoint\", \"windDir\",\n",
" \"windSpeed\", \"seaLevelPress\"]\n",
"multi_value_params = [\"presWeather\", \"skyCover\", \"skyLayerBase\"]\n",
"pres_weather, sky_cov, sky_layer_base = [],[],[]\n",
"params = single_value_params + multi_value_params\n",
"request.setParameters(*(params))\n",
"\n",
"# Time range\n",
"lastHourDateTime = datetime.utcnow() - timedelta(minutes = 60)\n",
"start = lastHourDateTime.strftime('%Y-%m-%d %H:%M:%S')\n",
"end = datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S')\n",
"\n",
"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",
"\n",
"# Get response\n",
"response = DataAccessLayer.getGeometryData(request,timerange)\n",
"# function getSynopticObs was added in python-awips 18.1.4\n",
"sfcobs = DataAccessLayer.getSynopticObs(response)\n",
"print(\"Found \" + str(len(response)) + \" records\")\n",
"print(\"Using \" + str(len(sfcobs['temperature'])) + \" temperature records\")"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 1152x864 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"data = dict()\n",
"data['stid'] = np.array(sfcobs['stationId'])\n",
"data['lat'] = np.array(sfcobs['latitude'])\n",
"data['lon'] = np.array(sfcobs['longitude'])\n",
"\n",
"# Synop/sfcobs temps are stored in kelvin (degC for METAR/obs)\n",
"tmp = np.array(sfcobs['temperature'], dtype=float)\n",
"dpt = np.array(sfcobs['dewpoint'], dtype=float)\n",
"direction = np.array(sfcobs['windDir'])\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_temperature'] = tmp * units.kelvin\n",
"data['dew_point_temperature'] = dpt * units.kelvin\n",
"data['air_pressure_at_sea_level'] = np.array(sfcobs['seaLevelPress'])* units('mbar')\n",
"try:\n",
" data['eastward_wind'], data['northward_wind'] = wind_components(\n",
" np.array(sfcobs['windSpeed']) * units('knots'),direction * units.degree)\n",
" data['present_weather'] = sfcobs['presWeather']\n",
"except ValueError:\n",
" pass\n",
"\n",
"fig_synop, ax_synop = make_map(bbox=bbox)\n",
"shape_feature = ShapelyFeature(states,ccrs.PlateCarree(), \n",
" facecolor='none', linestyle=\"-\",edgecolor='#000000',linewidth=2)\n",
"ax_synop.add_feature(shape_feature)\n",
"\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",
"ax_synop.set_title(str(response[-1].getDataTime()) + \" | SYNOP Surface Obs | \" + edexServer)\n",
"stationplot = StationPlot(ax_synop, data['lon'], data['lat'], clip_on=True,\n",
" transform=ccrs.PlateCarree(), fontsize=10)\n",
"custom_layout.plot(stationplot, data)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"\n",
"## Plot both METAR and SYNOP"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 1152x864 with 1 Axes>"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"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",
"ax.set_title(str(response[-1].getDataTime()) + \" | METAR/SYNOP Surface Obs | \" + edexServer)\n",
"stationplot = StationPlot(ax, data['lon'], data['lat'], clip_on=True,\n",
" transform=ccrs.PlateCarree(), fontsize=10)\n",
"custom_layout.plot(stationplot, data)\n",
"fig"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"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",
"version": "3.6.6"
}
},
"nbformat": 4,
"nbformat_minor": 1
}